// TODO Specify echarts path

const fs = require('fs');
const globby = require('globby');
const { buildExampleCode, collectDeps } = require('../common/buildCode');
const nodePath = require('path');
const { runTasks } = require('../common/task');
const fse = require('fs-extra');
const prettier = require('prettier');
const ts = require('typescript');
const chalk = require('chalk');
const nStatic = require('node-static');
const webpack = require('webpack');
const { RawSource } = require('webpack-sources');
const argparse = require('argparse');
const esbuild = require('esbuild');
const puppeteer = require('puppeteer');
const config = require('./config');
const { compareImage } = require('../common/compareImage');
const shell = require('shelljs');
const downloadGit = require('download-git-repo');
const { promisify } = require('util');
const matter = require('gray-matter');
const minimatch = require('minimatch');

const parser = new argparse.ArgumentParser({
  addHelp: true
});
parser.addArgument(['--bundler'], {
  help: 'Bundler, can be webpack or esbuild'
});
parser.addArgument(['-m', '--minify'], {
  action: 'storeTrue',
  help: 'If minify'
});
parser.addArgument(['--local'], {
  action: 'storeTrue',
  help: `If use local repos. If so, don't forget to update the location of local repo in config.js.`
});
parser.addArgument(['--skip'], {
  help: 'If skip some stages to speed up the test. Can be npm,bundle,render,compare'
});
parser.addArgument(['-t', '--tests'], {
  help: 'If use pattern to specify which tests to run'
});
const args = parser.parseArgs();

const EXAMPLE_DIR = nodePath.resolve(`${__dirname}/../public`);
const TMP_DIR = `${__dirname}/tmp`;
const RUN_CODE_DIR = `${TMP_DIR}/tests`;
const BUNDLE_DIR = `${TMP_DIR}/bundles`;
const SCREENSHOTS_DIR = `${TMP_DIR}/screenshots`;
const REPO_DIR = `${TMP_DIR}/repos`;
const PACKAGE_DIR = `${TMP_DIR}/packages`;

const MINIMAL_POSTFIX = 'minimal';
const MINIMAL_LEGACY_POSTFIX = 'minimal.legacy';

const MINIFY_BUNDLE = args.minify;
// const TEST_THEME = 'dark-blue';
const TEST_THEME = '';
const USE_WEBPACK = !(args.bundler === 'esbuild');

let testsPattern = args.tests;
if (testsPattern) {
  testsPattern = testsPattern.split(',');
}

// Create a server
const port = 3322;
const baseUrl = `http://localhost:${port}`;

const TEMPLATE_CODE = `
// @ts-ignore
echarts.registerPreprocessor(function (option) {
    option.animation = false;
    if (option.series) {
        if (!(option.series instanceof Array)) {
            option.series = [option.series];
        }
        // @ts-ignore
        option.series.forEach(function (seriesOpt) {
            if (seriesOpt.type === 'graph') {
                seriesOpt.force = seriesOpt.force || {};
                seriesOpt.force.layoutAnimation = false;
            }
            seriesOpt.progressive = 1e5;
            seriesOpt.animation = false;
        });
    }
});
`;

function buildPrepareCode(isESM, lang) {
  return `
// @ts-ignore
${
  isESM
    ? `import _seedrandom from 'seedrandom';`
    : `const _seedrandom = require('seedrandom');`
}

// Check if i18n will break the minimal imports.
${
  lang
    ? isESM
      ? `import 'echarts/i18n/${lang}';`
      : `require('echarts/i18n/${lang}');`
    : ''
}
// @ts-ignore
const _myrng = _seedrandom('echarts');
// @ts-ignore
Math.random = function () {
    // @ts-ignore
    return _myrng();
};
${TEMPLATE_CODE}
`;
}

async function prepare() {
  fse.removeSync(TMP_DIR);
  fse.removeSync(RUN_CODE_DIR);
  fse.removeSync(BUNDLE_DIR);
  fse.removeSync(SCREENSHOTS_DIR);

  fse.removeSync(REPO_DIR);
  fse.removeSync(PACKAGE_DIR);

  fse.ensureDirSync(TMP_DIR);
  fse.ensureDirSync(RUN_CODE_DIR);
  fse.ensureDirSync(BUNDLE_DIR);
  fse.ensureDirSync(SCREENSHOTS_DIR);

  fse.ensureDirSync(REPO_DIR);
  fse.ensureDirSync(PACKAGE_DIR);
}

async function downloadPackages(config) {
  for (let pkg of config.packages) {
    const pkgDownloadPath = nodePath.join(REPO_DIR, pkg.name);
    console.log(chalk.gray(`Downloading ${pkg.git}`));
    await promisify(downloadGit)(pkg.git, pkgDownloadPath);
    // Override the path
    pkg.dir = pkgDownloadPath;
  }
}

async function installPackages(config) {
  const publishedPackages = {};

  function checkFolder(pkg) {
    const dir = pkg.dir;
    if (!fs.existsSync(dir)) {
      console.warn(
        chalk.yellow(`${dir} not exists. Please update it in e2e/config.js.`)
      );
      return false;
    }
    if (!nodePath.isAbsolute(dir)) {
      console.warn(
        chalk.yellow(
          `${dir} is not an absolute path. Please update it in e2e/config.js.`
        )
      );
      return false;
    }
    return true;
  }

  function publishPackage(pkg) {
    console.log(chalk.gray(`Publishing ${pkg.dir}`));

    shell.cd(pkg.dir);

    const packageJson = JSON.parse(
      fs.readFileSync(nodePath.join(pkg.dir, 'package.json'))
    );
    const tgzFileName = `${packageJson.name}-${packageJson.version}.tgz`;
    const targetTgzFilePath = nodePath.join(PACKAGE_DIR, tgzFileName);

    if (packageJson.dependencies) {
      for (let depPkgName in packageJson.dependencies) {
        const depPkg = config.packages.find((a) => a.name === depPkgName);
        if (depPkg && !publishedPackages[depPkgName]) {
          publishPackage(depPkg);
          // Come back.
          shell.cd(pkg.dir);
        }

        shell.exec(`npm install`);

        if (depPkg) {
          console.log(
            chalk.gray(
              `Installing dependency ${depPkgName} from "${publishedPackages[depPkgName]}" ...`
            )
          );
          shell.exec(`npm install ${publishedPackages[depPkgName]} --no-save`);
          console.log(chalk.gray(`Install dependency ${depPkgName} done.`));
        }
      }
    }

    shell.exec(`npm pack`);
    fs.renameSync(nodePath.join(pkg.dir, tgzFileName), targetTgzFilePath);
    publishedPackages[packageJson.name] = targetTgzFilePath;
  }

  for (let pkg of config.packages) {
    if (!checkFolder(pkg)) {
      return;
    }

    publishPackage(pkg);
  }

  shell.cd(__dirname);
  for (let pkg of config.packages) {
    console.log(
      chalk.gray(
        `Installing ${pkg.name} from "${publishedPackages[pkg.name]}" ...`
      )
    );
    shell.exec(`npm install ${publishedPackages[pkg.name]} --no-save`);
    console.log(chalk.gray(`Install ${pkg.name} done.`));
  }

  // Come back.
  shell.cd(process.cwd());
}

async function buildRunCode() {
  const files = await globby([
    `${EXAMPLE_DIR}/data/option/*.json`,
    `${EXAMPLE_DIR}/data-gl/option/*.json`
  ]);

  if (!files.length) {
    throw new Error(
      'You need to run `node tool/build-example.js` before run this test.'
    );
  }

  async function addTestCase(
    testName,
    testCode,
    deps,
    checkTs,
    extraImports,
    extraRequire
  ) {
    const ROOT_PATH = `${baseUrl}/public`;

    const fullCode = buildExampleCode(buildPrepareCode(true) + testCode, deps, {
      minimal: false,
      ts: checkTs,
      // Check if theme will break the minimal imports.
      theme: TEST_THEME,
      ROOT_PATH,
      extraImports
    });
    const minimalCode = buildExampleCode(
      buildPrepareCode(true) + testCode,
      deps,
      {
        minimal: true,
        ts: checkTs,
        theme: TEST_THEME,
        ROOT_PATH,
        extraImports
      }
    );
    const legacyCode = buildExampleCode(
      buildPrepareCode(false) + testCode,
      deps,
      {
        minimal: true,
        esm: false,
        ts: false,
        theme: TEST_THEME,
        ROOT_PATH,
        extraImports: extraRequire
      }
    );

    await fse.writeFile(
      nodePath.join(RUN_CODE_DIR, testName + (checkTs ? '.ts' : '.js')),
      prettier.format(fullCode, {
        singleQuote: true,
        parser: checkTs ? 'typescript' : 'babel'
      }),
      'utf-8'
    );
    await fse.writeFile(
      nodePath.join(
        RUN_CODE_DIR,
        testName + `.${MINIMAL_POSTFIX}.${checkTs ? 'ts' : 'js'}`
      ),
      prettier.format(minimalCode, {
        singleQuote: true,
        parser: checkTs ? 'typescript' : 'babel'
      }),
      'utf-8'
    );
    await fse.writeFile(
      nodePath.join(RUN_CODE_DIR, testName + `.${MINIMAL_LEGACY_POSTFIX}.js`),
      prettier.format(legacyCode, {
        singleQuote: true,
        parser: 'babel'
      }),
      'utf-8'
    );
    console.log(chalk.green('Generated: ', testName));
  }

  const builtinTestCases = await runTasks(
    files,
    async (fileName) => {
      const isGL = fileName.startsWith(`${EXAMPLE_DIR}/data-gl`);
      const testName = nodePath.basename(fileName, '.json');

      if (
        testsPattern &&
        !testsPattern.some((pattern) => minimatch(testName, pattern))
      ) {
        return;
      }

      const optionCode = await fse.readFile(fileName, 'utf-8');
      let option;
      try {
        option = JSON.parse(optionCode);
      } catch (err) {
        console.error(
          `Parse JSON error: fileName: ${fileName} | fileContent: ${optionCode}`
        );
        throw err;
      }
      const testCode = await fse.readFile(
        nodePath.join(EXAMPLE_DIR, isGL ? 'data-gl' : 'data', testName + '.js'),
        'utf-8'
      );

      // TODO Ignore case with extension.

      const deps = collectDeps(option).concat([
        // TODO SVG
        'CanvasRenderer'
      ]);

      if (
        !(testName === 'map-HK' || testName === 'map-usa') && // Only test these two map examples
        (deps.includes('MapChart') ||
          deps.includes('GeoComponent') ||
          option.bmap)
      ) {
        console.warn(chalk.yellow(`Ignored map tests ${testName}`));
        return;
      }

      // TODO: Don't support TypeScript in GL
      await addTestCase(testName, testCode, deps, !isGL);

      return testName;
    },
    20
  );
  const extensionTestCases = await runTasks(
    await globby(__dirname + '/cases/*.js'),
    async (fileName) => {
      const testName = nodePath.basename(fileName, '.js');
      if (
        testsPattern &&
        !testsPattern.some((pattern) => minimatch(testName, pattern))
      ) {
        return;
      }

      const testCode = await fse.readFile(fileName, 'utf-8');
      let importsCode = '';
      let requireCode = '';
      try {
        const fmResult = matter(testCode, {
          delimiters: ['/*', '*/']
        });
        const extension = fmResult.data.extension;
        if (extension) {
          importsCode = `import '${extension}';`;
          requireCode = `require('${extension}');`;
        }
      } catch (e) {}
      await addTestCase(
        testName,
        testCode,
        [],
        false,
        importsCode,
        requireCode
      );

      return testName;
    },
    20
  );

  return builtinTestCases.concat(extensionTestCases).filter((a) => !!a);
}

async function compileTs(tsTestFiles, result) {
  const config = JSON.parse(
    fs.readFileSync(nodePath.join(__dirname, 'tsconfig.json'), 'utf-8')
  );

  const compilerOptions = {
    ...config.compilerOptions
  };

  const { options, errors } = ts.convertCompilerOptionsFromJson(
    compilerOptions,
    nodePath.resolve(__dirname)
  );

  if (errors.length) {
    let errMsg =
      'tsconfig parse failed: ' +
      errors.map((error) => error.messageText).join('. ') +
      '\n compilerOptions: \n' +
      JSON.stringify(config.compilerOptions, null, 4);
    assert(false, errMsg);
  }

  // Generate this config file for checking the source code in vscode.
  fs.writeFileSync(
    nodePath.join(RUN_CODE_DIR, 'tsconfig.json'),
    JSON.stringify(
      {
        compilerOptions
      },
      null,
      2
    ),
    'utf-8'
  );

  // See: https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
  let program = ts.createProgram(tsTestFiles, options);
  let emitResult = program.emit();

  let allDiagnostics = ts
    .getPreEmitDiagnostics(program)
    .concat(emitResult.diagnostics);

  allDiagnostics.forEach((diagnostic) => {
    if (diagnostic.file) {
      let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(
        diagnostic.start
      );
      let message = ts.flattenDiagnosticMessageText(
        diagnostic.messageText,
        '\n'
      );

      const compilerError = {
        location: [line + 1, character + 1],
        message
      };
      if (diagnostic.file.fileName.endsWith(`${MINIMAL_POSTFIX}.ts`)) {
        const basename = nodePath.basename(
          diagnostic.file.fileName,
          `.${MINIMAL_POSTFIX}.ts`
        );
        if (!result[basename]) {
          throw new Error(`${basename} does not exists in result.`);
        }
        result[basename].compileErrors.minimal.push(compilerError);
      } else {
        const basename = nodePath.basename(diagnostic.file.fileName, `.ts`);
        if (!result[basename]) {
          throw new Error(`${basename} does not exists in result.`);
        }
        result[basename].compileErrors.full.push(compilerError);
      }
      // console.log(chalk.red(`${diagnostic.file.fileName} (${line + 1},${character + 1})`));
      // console.log(chalk.gray(message));
    } else {
      console.log(
        chalk.red(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'))
      );
    }
  });
  // assert(!emitResult.emitSkipped, 'ts compile failed.');
}

async function webpackBundle(esbuildService, entry, result) {
  return new Promise((resolve) => {
    webpack(
      {
        entry,
        output: {
          path: BUNDLE_DIR,
          filename: '[name].js'
        },
        // Use esbuild as minify, terser is tooooooo slow for so much tests.
        optimization: {
          minimizer: MINIFY_BUNDLE
            ? [
                {
                  apply(compiler) {
                    compiler.hooks.compilation.tap(
                      'ESBuild Minify',
                      (compilation) => {
                        compilation.hooks.optimizeChunkAssets.tapPromise(
                          'ESBuild Minify',
                          async (chunks) => {
                            for (const chunk of chunks) {
                              for (const file of chunk.files) {
                                const asset = compilation.assets[file];
                                const { source } = asset.sourceAndMap();
                                const result = await esbuildService.transform(
                                  source,
                                  {
                                    minify: true,
                                    sourcemap: false
                                  }
                                );
                                compilation.updateAsset(file, () => {
                                  return new RawSource(result.code || '');
                                });
                              }
                            }
                          }
                        );
                      }
                    );
                  }
                }
              ]
            : []
        }
      },
      (err, stats) => {
        if (err || stats.hasErrors()) {
          if (err) {
            console.error(err.stack || err);
            if (err.details) {
              console.error(err.details);
            }
            resolve();
            return;
          }

          const info = stats.toJson();

          if (stats.hasErrors()) {
            console.error(info.errors);
          }

          if (stats.hasWarnings()) {
            console.warn(info.warnings);
          }
        } else {
          console.log(
            chalk.green(
              `${Object.values(entry)
                .map((a) => `Bundled ${a}`)
                .join('\n')}`
            )
          );
        }

        resolve();
      }
    );
  });
}

function esbuildBundle(entry, result, minify) {
  return esbuild.build({
    entryPoints: entry,
    bundle: true,
    minify: minify,
    define: {
      'process.env.NODE_ENV': JSON.stringify(
        minify ? 'production' : 'development'
      )
    },
    outdir: BUNDLE_DIR
  });
}

async function bundle(entryFiles, result) {
  if (USE_WEBPACK) {
    // Split to multiple buckets to seepup bundle
    // TODO Multiple entry may have effects on the final bundle.
    const BUCKET_SIZE = 1;
    const buckets = [];
    const esbuildService = await esbuild.startService();
    let count = 0;
    outer: while (true) {
      const bucket = {};
      for (let i = 0; i < BUCKET_SIZE; i++) {
        const filePath = entryFiles[count++];
        if (!filePath) {
          break outer;
        }
        const basename = nodePath.basename(filePath, '.js');
        bucket[basename] = filePath;
      }
      buckets.push(bucket);
    }

    // TODO Multiple thread.
    for (let bucket of buckets) {
      await webpackBundle(esbuildService, bucket, result);
    }

    esbuildService.stop();
  } else {
    for (let file of entryFiles) {
      await esbuildBundle([file], result, MINIFY_BUNDLE);
      console.log(chalk.green(`Bundled ${file}`));
    }
  }
}

function waitTime(time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}
async function runExamples(jsFiles, result) {
  const fileServer = new nStatic.Server(__dirname + '/../');
  const server = require('http').createServer(function (request, response) {
    request
      .addListener('end', function () {
        fileServer.serve(request, response);
      })
      .resume();
  });
  server.listen(port);

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

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

    await runTasks(
      jsFiles,
      async (file) => {
        const page = await browser.newPage();
        const basename = nodePath.basename(file, '.js');
        await page.setViewport({ width: 800, height: 600 });

        page.on('pageerror', function (err) {
          // TODO Record pageerror
          console.error(chalk.red(`[PAGE ERROR] [${basename}]`));
          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}`));
          }
        });

        await page.goto(`${baseUrl}/e2e/template.html`, {
          waitUntil: 'networkidle0',
          timeout: 10000
        });
        await page.addScriptTag({
          url: `${baseUrl}/e2e/tmp/bundles/${basename}.js`
        });
        await waitTime(200);

        await page.screenshot({
          type: 'png',
          path: nodePath.resolve(SCREENSHOTS_DIR, basename + '.png')
        });

        await page.close();

        console.log(chalk.green(`Rendered ${file}`));
      },
      8
    );
  } catch (e) {
    server.close();
    throw e;
  }
}

async function compareExamples(testNames, result) {
  function writePNG(png, diffPath) {
    return new Promise((resolve) => {
      const writer = fs.createWriteStream(diffPath);
      png.pack().pipe(writer);
      writer.on('finish', () => {
        resolve();
      });
    });
  }

  for (let testName of testNames) {
    const diffMinimal = await compareImage(
      nodePath.resolve(SCREENSHOTS_DIR, testName + '.png'),
      nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_POSTFIX}.png`)
    );
    const diffMinimalLegacy = await compareImage(
      nodePath.resolve(SCREENSHOTS_DIR, testName + '.png'),
      nodePath.resolve(
        SCREENSHOTS_DIR,
        `${testName}.${MINIMAL_LEGACY_POSTFIX}.png`
      )
    );

    const diffMinimalPNGPath = nodePath.resolve(
      SCREENSHOTS_DIR,
      `${testName}.${MINIMAL_POSTFIX}.diff.png`
    );
    const diffMinimalLegacyPNGPath = nodePath.resolve(
      SCREENSHOTS_DIR,
      `${testName}.${MINIMAL_LEGACY_POSTFIX}.diff.png`
    );

    writePNG(diffMinimal.diffPNG, diffMinimalPNGPath);
    writePNG(diffMinimalLegacy.diffPNG, diffMinimalLegacyPNGPath);

    result[testName].screenshotDiff = {
      minimal: {
        ratio: diffMinimal.diffRatio,
        png: nodePath.basename(diffMinimalPNGPath)
      },
      minimalLegacy: {
        ratio: diffMinimalLegacy.diffRatio,
        png: nodePath.basename(diffMinimalLegacyPNGPath)
      }
    };

    if (diffMinimal.diffRatio > 0 || diffMinimalLegacy.diffRatio > 0) {
      console.log(chalk.red(`Failed ${testName}`));
    } else {
      console.log(chalk.green(`Passed ${testName}`));
    }
  }
}

async function main() {
  let result;

  if (!args.skip && !args.tests) {
    // Don't clean up if skipping some of the stages.
    await prepare();
    result = {};
  } else {
    // Read result.
    try {
      result = JSON.parse(
        fs.readFileSync(__dirname + '/tmp/result.json', 'utf-8')
      );
    } catch (e) {
      console.error(e);
      throw 'Must run full e2e test without --skip and --tests at least once.';
    }
  }

  function isNotSkipped(stage) {
    return !((args.skip || '').indexOf(stage) >= 0);
  }

  // We don't have to test the npm if bundle is also skipped.
  if (isNotSkipped('npm') && isNotSkipped('bundle')) {
    if (!args.local) {
      console.log(chalk.gray('Downloading packages'));
      await downloadPackages(config);
    }

    console.log(chalk.gray('Installing packages'));
    await installPackages(config);
  } else {
    console.log(chalk.yellow('Skipped NPM.'));
  }

  console.log(chalk.gray('Generating codes'));
  // Always build code.
  const testNames = await buildRunCode();

  for (let key of testNames) {
    result[key] = result[key] || {};
  }

  Object.keys(result).forEach((key) => {
    // Always do TS check on all tests. So reset all compile errors.
    result[key].compileErrors = {
      full: [],
      minimal: [],
      minimalLegacy: []
    };
  });

  console.log('Compiling TypeScript');
  // Always run typescript check to generate the js code.
  await compileTs(
    (
      await globby(nodePath.join(RUN_CODE_DIR, '*.ts'))
    )
      // No need to check types of the minimal legacy imports
      .filter((a) => !a.endsWith(`${MINIMAL_LEGACY_POSTFIX}.ts`)),
    result
  );

  if (isNotSkipped('bundle')) {
    console.log(
      chalk.green(`Bundling with ${USE_WEBPACK ? 'webpack' : 'esbuild'}`)
    );
    const jsFiles = [];
    for (let testName of testNames) {
      jsFiles.push(
        nodePath.join(RUN_CODE_DIR, `${testName}.js`),
        nodePath.join(RUN_CODE_DIR, `${testName}.${MINIMAL_POSTFIX}.js`),
        nodePath.join(RUN_CODE_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.js`)
      );
    }
    await bundle(jsFiles, result);
  } else {
    console.log(chalk.yellow('Skipped Bundle.'));
  }

  if (isNotSkipped('render')) {
    console.log(chalk.green('Running examples'));
    const bundleFiles = [];
    for (let testName of testNames) {
      bundleFiles.push(
        nodePath.join(BUNDLE_DIR, `${testName}.js`),
        nodePath.join(BUNDLE_DIR, `${testName}.${MINIMAL_POSTFIX}.js`),
        nodePath.join(BUNDLE_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.js`)
      );
    }
    await runExamples(bundleFiles, result);
  } else {
    console.log(chalk.yellow('Skipped Render.'));
  }

  if (isNotSkipped('compare')) {
    console.log(chalk.green('Comparing Results'));
    await compareExamples(testNames, result);
  } else {
    console.log(chalk.yellow('Skipped Compare.'));
  }

  fs.writeFileSync(
    __dirname + '/tmp/result.json',
    JSON.stringify(result, null, 2),
    'utf-8'
  );
}

main()
  .catch((e) => {
    console.error(e);
    process.exit();
  })
  .then(() => {
    process.exit();
  });

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