const fs = require('fs');
const globby = require('globby');
const path = require('path');
const matter = require('gray-matter');
const argparse = require('argparse');
const minimatch = require('minimatch');
const { execFile } = require('child_process');
const cwebpBin = require('cwebp-bin');
const util = require('util');
const chalk = require('chalk');
const sharp = require('sharp');
const fse = require('fs-extra');
const { compareImage } = require('../common/compareImage');
const { runTasks } = require('../common/task');
const nStatic = require('node-static');
const shell = require('shelljs');

function optionToJson(obj, prop) {
  let json = JSON.stringify(
    obj,
    function (key, value) {
      if (typeof value === 'function') {
        return 'expr: ' + value.toString();
      }
      return value;
    },
    2
  );
  return json;
}
function codeSize(code) {
  return Buffer.byteLength(code, 'utf-8');
}

const parser = new argparse.ArgumentParser({
  addHelp: true
});
parser.addArgument(['--gl'], {
  help: 'If generating gl',
  action: 'storeTrue'
});
parser.addArgument(['-t', '--theme'], {
  help: 'Theme list, default to be all'
});
parser.addArgument(['-p', '--pattern'], {
  help: 'Glob match patterns for generating thumb. https://github.com/isaacs/minimatch Multiple match pattens can be split with ,'
});
parser.addArgument(['--no-thumb'], {
  help: 'If not generate thumbs',
  action: 'storeTrue'
});

const args = parser.parseArgs();
const isGL = args.gl;
let themeList = args.theme || 'default,dark';
let matchPattern = args.pattern;
if (matchPattern) {
  matchPattern = matchPattern.split(',');
}
themeList = themeList.split(',');

function waitTime(time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

const BUILD_THUMBS = !args.no_thumb;
const DEFAULT_PAGE_WIDTH = 700;
const DEFAULT_PAGE_RATIO = 0.75;
const OUTPUT_IMAGE_WIDTH = 600;
const OUTPUT_IMAGE_HEIGHT = OUTPUT_IMAGE_WIDTH * DEFAULT_PAGE_RATIO;

const PORT = 3323;
const BASE_URL = `http://localhost:${PORT}`;
const SCREENSHOT_PAGE_URL = `${BASE_URL}/tool/screenshot.html`;

const IGNORE_LOG = [
  // For BMap
  'A cookie associated with a cross-site resource at',
  'A parser-blocking, cross site',
  // For ECharts GL
  'RENDER WARNING',
  'GL ERROR',
  'GL_INVALID_OPERATION'
];

function checkHasVideo(videoStart, videoEnd) {
  return !isNaN(videoStart) && !isNaN(videoEnd) && +videoEnd > +videoStart;
}

async function convertToWebP(filePath) {
  return util.promisify(execFile)(cwebpBin, [
    filePath,
    '-o',
    filePath.replace(/\.png$/, '.webp')
  ]);
}

async function takeScreenshot(
  browser,
  ffmpeg,
  theme,
  rootDir,
  basename,
  hasVideo,
  // Shot parameters
  { shotWidth, shotDelay, videoStart, videoEnd }
) {
  const thumbFolder = theme !== 'default' ? 'thumb-' + theme : 'thumb';
  const page = await browser.newPage();
  const dataDir = isGL ? 'data-gl' : 'data';
  const thumbDir = `${rootDir}public/${dataDir}/${thumbFolder}`;
  const fileBase = `${thumbDir}/${basename}`;
  const webmFile = `${fileBase}.webm`;

  function checkDownloadFile() {
    return new Promise((resolve) => {
      let timeout = 0;
      function check() {
        if (fs.existsSync(webmFile)) {
          resolve();
          return;
        }
        timeout += 100;
        if (timeout >= 20000 + +videoEnd) {
          console.error(fileBase + '.webm download timeout.');
          resolve();
          return;
        }

        setTimeout(check, 100);
      }
      setTimeout(check, 100);
    });
  }

  let checkingDownload;

  await page.setViewport({
    width: shotWidth || DEFAULT_PAGE_WIDTH,
    height: (shotWidth || DEFAULT_PAGE_WIDTH) * DEFAULT_PAGE_RATIO
  });
  let url = `${SCREENSHOT_PAGE_URL}?c=${basename}&t=${theme}${
    isGL ? '&gl' : ''
  }`;

  if (hasVideo) {
    url += `&start=${videoStart}&end=${videoEnd}`;
    await page._client.send('Page.setDownloadBehavior', {
      behavior: 'allow',
      downloadPath: thumbDir
    });

    checkingDownload = checkDownloadFile();
  }

  const resourceRootPath = `${BASE_URL}/public`;
  // console.log(url);
  await page.evaluateOnNewDocument(function (resourceRootPath) {
    window.ROOT_PATH = resourceRootPath;
  }, resourceRootPath);

  page.on('pageerror', function (err) {
    console.error(chalk.red('[pageerror in]', url));
    console.error(chalk.red(err.toString()));
  });
  page.on('console', (msg) => {
    const text = msg.text();
    if (!IGNORE_LOG.find((a) => text.indexOf(a) >= 0)) {
      console.log(chalk.gray(`PAGE LOG[${basename}]: ${text}`));
    }
  });

  console.log(`Generating ${theme} thumbs.....${basename}`);
  // https://stackoverflow.com/questions/46160929/puppeteer-wait-for-all-images-to-load-then-take-screenshot
  try {
    try {
      await page.goto(url, {
        waitUntil: 'networkidle0',
        timeout: 20000
      });
    } catch (e) {
      console.error(chalk.red(e));
      // Timeout
    }
    await waitTime(200);
    await waitTime(shotDelay || 0);
    const filePathTmpRaw = `${fileBase}-tmp-raw.png`;
    const filePathTmp = `${fileBase}-tmp.png`;
    const filePath = `${fileBase}.png`;

    fse.ensureDirSync(thumbDir);

    // Save option for further tests.
    try {
      const option = await page.evaluate(() => {
        return _$getEChartsOption();
      });
      const optionStr = optionToJson(option);
      fse.ensureDirSync(`${rootDir}public/${dataDir}/option/`);
      fs.writeFileSync(
        `${rootDir}public/${dataDir}/option/${basename}.json`,
        optionStr,
        'utf-8'
      );
    } catch (e) {
      console.error(chalk.red('Failed to generate option'));
      console.error(chalk.red(e));
    }

    await page.screenshot({
      path: filePathTmpRaw,
      type: 'png'
    });

    await sharp(filePathTmpRaw)
      .resize(OUTPUT_IMAGE_WIDTH, OUTPUT_IMAGE_HEIGHT)
      .toFile(filePathTmp);

    const { diffRatio } = await compareImage(filePath, filePathTmp, 0.1);

    console.log(filePath);
    if (diffRatio < 0.01) {
      console.log('Not changed');
    } else {
      console.log(diffRatio);
      fs.copyFileSync(filePathTmp, filePath);
      if (!hasVideo) {
        await convertToWebP(filePath);
      }
    }

    try {
      fs.unlinkSync(filePathOld);
    } catch (e) {}

    fs.unlinkSync(filePathTmpRaw);
    fs.unlinkSync(filePathTmp);

    if (hasVideo) {
      await checkingDownload;
      // const webpFile = `${fileBase}.webp`;
      // const fileContent = fs.readFileSync(webmFile);
      // ffmpeg.FS('writeFile', `${basename}.webm`, await fetchFile(fileContent));
      // await ffmpeg.run('-i', `${basename}.webm`, '-f', 'webp', '-s', `${OUTPUT_IMAGE_WIDTH}x${OUTPUT_IMAGE_HEIGHT}`, `${basename}.webp`);
      // fs.writeFileSync(webpFile, ffmpeg.FS('readFile', `${basename}.webp`));
      // ffmpeg.FS("unlink", `${basename}.webm`)
      // ffmpeg.FS("unlink", `${basename}.webp`)
      shell.exec(
        `ffmpeg -y -i "${fileBase}.webm" -s ${OUTPUT_IMAGE_WIDTH}x${OUTPUT_IMAGE_HEIGHT} -f webp "${fileBase}.webp"`
      );
      try {
        fs.unlinkSync(webmFile);
      } catch (e) {}
    }
  } catch (e) {
    console.error(url);
    console.error(e.toString());
  }
  await page.close();
}

(async () => {
  const rootDir = path.join(__dirname, '../');
  // TODO puppeteer will have Navigation Timeout Exceeded: 30000ms exceeded error in these examples.
  const screenshotBlackList = [];

  const examplesRoot = `${rootDir}public/examples`;
  const files = await globby(`js/${isGL ? 'gl/' : ''}*.js`, {
    cwd: examplesRoot,
    absolute: true
  });

  const exampleList = [];

  let thumbTasks = [];

  for (let theme of themeList) {
    for (let fileName of files) {
      const basename = path.basename(fileName, '.js');

      // Remove mapbox temporary
      if (
        basename.indexOf('mapbox') >= 0 ||
        basename.indexOf('shanghai') >= 0 ||
        basename === 'lines3d-taxi-routes-of-cape-town' ||
        basename === 'lines3d-taxi-chengdu' ||
        basename === 'map3d-colorful-cities' ||
        // TODO Examples that can't work temporary.
        basename === 'bar3d-music-visualization'
      ) {
        continue;
      }

      const tsFile = `${examplesRoot}/ts/${isGL ? 'gl/' : ''}${basename}.ts`;
      const hasTs = fs.existsSync(tsFile);

      let fmResult;
      try {
        const code = fs.readFileSync(fileName, 'utf-8');
        fmResult = matter(code, {
          delimiters: ['/*', '*/']
        });
      } catch (e) {
        fmResult = {
          data: {}
        };
      }

      try {
        const difficulty =
          fmResult.data.difficulty != null ? fmResult.data.difficulty : 10;
        const category = (fmResult.data.category || '')
          .split(/,/g)
          .map((a) => a.trim())
          .filter((a) => !!a);
        if (!exampleList.find((item) => item.id === basename)) {
          // Avoid add multiple times when has multiple themes.
          exampleList.push({
            category: category,
            id: basename,
            ts: hasTs,
            tags: (fmResult.data.tags || '')
              .split(/,/g)
              .map((a) => a.trim())
              .filter((a) => !!a),
            theme: fmResult.data.theme,
            title: fmResult.data.title,
            titleCN: fmResult.data.titleCN,
            difficulty: +difficulty
          });
        }
      } catch (e) {
        throw new Error(e.toString());
      }

      if (
        !matchPattern ||
        (matchPattern.some(function (pattern) {
          return minimatch(basename, pattern);
        }) &&
          screenshotBlackList.indexOf(basename) < 0)
      ) {
        thumbTasks.push({
          theme,
          fmResult,
          basename
        });
      }
    }
  }

  exampleList.sort(function (a, b) {
    if (a.difficulty === b.difficulty) {
      return a.id.localeCompare(b.id);
    }
    return a.difficulty - b.difficulty;
  });

  const code = `
/* eslint-disable */
// THIS FILE IS GENERATED, DON'T MODIFY */
export default ${JSON.stringify(exampleList, null, 2)}`;

  if (!matchPattern) {
    fs.writeFileSync(
      path.join(
        __dirname,
        `../src/data/chart-list-data${isGL ? '-gl' : ''}.js`
      ),
      code,
      'utf-8'
    );
  }

  // Do screenshot
  if (BUILD_THUMBS) {
    const fileServer = new nStatic.Server(rootDir);
    const server =
      BUILD_THUMBS &&
      require('http').createServer(function (request, response) {
        request
          .addListener('end', function () {
            fileServer.serve(request, response);
          })
          .resume();
      });
    server && server.listen(PORT);

    const puppeteer = require('puppeteer');
    const browser = await puppeteer.launch({
      headless: false,
      args: [
        '--headless',
        '--hide-scrollbars',
        // https://github.com/puppeteer/puppeteer/issues/4913
        '--use-gl=egl',
        '--mute-audio'
      ]
    });

    let ffmpeg;
    // const ffmpeg = createFFmpeg({ log: true });
    // await ffmpeg.load();

    try {
      // Take screenshots
      const animationTasks = thumbTasks.filter((task) => {
        return checkHasVideo(
          task.fmResult.data.videoStart,
          task.fmResult.data.videoEnd
        );
      });
      const staticTasks = thumbTasks.filter((task) => {
        return !checkHasVideo(
          task.fmResult.data.videoStart,
          task.fmResult.data.videoEnd
        );
      });
      await runTasks(
        staticTasks,
        async ({ basename, fmResult, theme }) => {
          await takeScreenshot(
            browser,
            ffmpeg,
            theme,
            rootDir,
            basename,
            false,
            {
              shotWidth: fmResult.data.shotWidth,
              shotDelay: fmResult.data.shotDelay
            }
          );
        },
        isGL ? 2 : 16
      );

      await runTasks(
        animationTasks,
        async ({ basename, fmResult, theme }) => {
          await takeScreenshot(
            browser,
            ffmpeg,
            theme,
            rootDir,
            basename,
            true,
            {
              shotWidth: fmResult.data.shotWidth,
              shotDelay: fmResult.data.shotDelay,
              videoStart: fmResult.data.videoStart,
              videoEnd: fmResult.data.videoEnd
            }
          );
        },
        1
      ); // Webm download seems has issue used with multithreads
    } catch (e) {
      server.close();
      await browser.close();
      throw new Error(e.toString());
    }

    server.close();
    await browser.close();
    // ffmpeg.exit(0);
  }
})();

process.on('SIGINT', function () {
  console.log('Closing');
  server.close();
  // Close through ctrl + c;
  process.exit();
});
