const util = require('util');
const path = require('path');
const fs = require('fs');
const ora = require('ora');
const puppeteer = require('puppeteer');

module.exports = async (obj) => {

  const dirname = process.argv[1].replace('/bin/canvasxpress', '');

  const today = new Date().toISOString().replace('-', '').split('T')[0].replace('-', '');

  const logFile = fs.createWriteStream(('/tmp/io-' + today + '.log'), { flags: 'a' });

  const logStdout = process.stdout;

  const html = (obj.input && obj.input.match(/.html$/) ? obj.input : ("file://" + dirname + "/src/canvasXpress.html")) + (obj.debug ? "?cXH" : "");

  console.log = function () {
    logFile.write(util.format.apply(null, arguments) + '\n');
    logStdout.write(util.format.apply(null, arguments) + '\n');
  }
  console.error = console.log;

  const spinner = ora().start();

  try {

    const browser = await puppeteer.launch({
      headless: obj.debug ? false : true,
      devtools: obj.debug ? true : false,
      executablePath: puppeteer.executablePath(),
      defaultViewport: {
        width: 1000,
        height: 1000
      },
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--allow-file-access-from-files',
        '--enable-local-file-accesses'
      ]
    });

    const page = await browser.newPage();

    page.on("console", (consoleObj) => console.log(consoleObj.text()));

    if (obj.input && !obj.input.match(/^file|^http/)) {
      obj.input = "file://" + path.resolve(obj.input);
    }

    const func = function (obj) {

      if (obj.debug) {
        debugger;
      }

      var exec = function (cx, tg) {
        switch (obj.cmd) {
          case 'png':
            cx.print(false, tg + '.png');
            break;
          case 'svg':
            cx.saveSVG(false, tg + '.svg');
            break;
          case 'json':
            cx.save(false, tg + '.json');
            break;
        }
      }

      var clbk = function () {
        var cx = CanvasXpress.instances[1];
        console.log(logStr);
        exec(cx, cx.target);
      }

      var cx = CanvasXpress.instances[0];

      const extFile = obj.input ? obj.input.split(".").pop() : false;

      const logStr = "Creating " + obj.cmd + " file from " + (obj.input ? obj.input : 'input data') + " (" + obj.output + (obj.target || cx.target) + (extFile == 'html' ? '' : '-1') + "." + obj.cmd + ")";

      cx.setDimensions(obj.width, obj.height);

      if (obj.input) {
        try {
          switch (extFile) {
            case 'html':
              console.log(logStr);
              exec(cx, obj.target || cx.target);
              return;
            case 'json':
            case 'csv':
            case 'text':
            case 'png':
              cx.dataURL = obj.input;
              cx.remoteTransitionEffect = 'none';
              cx.getDataFromURLOrString(obj.target || cx.target, obj.config, false, false, clbk);
              return;
          }
        } catch (err) {
          console.error(err);
        }
      } else if (obj.data) {
        try {
          console.log(logStr);
          cx.updateData(obj.data, false, false, obj.config);
          exec(cx, obj.target || cx.target);
          return;
        } catch (err) {
          console.error(err);
        }
      }

    }

    const client = await page.target().createCDPSession();

    await client.send('Page.setDownloadBehavior', {
      behavior: 'allow',
      downloadPath: obj.output
    })

    await page.goto(html);

    await page.waitForFunction('typeof (CanvasXpress) !== undefined && CanvasXpress.ready');

    await page.evaluate(`(${func.toString()})(${JSON.stringify(obj)})`);

    await setTimeout(() => {
      browser.close();
      spinner.stop();
    }, obj.tmout);

  } catch (err) {

    console.error(err);

  }

}