// 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 PUBLIC_DIR = nodePath.resolve(`${__dirname}/../public`);
const EXAMPLE_DIR = nodePath.resolve(`${PUBLIC_DIR}/examples`);
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([
    `${PUBLIC_DIR}/data/option/*.json`,
    `${PUBLIC_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(`${PUBLIC_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, 'js', isGL ? 'gl' : '', 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;
      }

      // Do typescript check in compile:example
      await addTestCase(testName, testCode, deps, false);

      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`
    );

    if (!diffMinimal.diffPNG) {
      console.error(`Screenshot Error in ${testName}`);
    } else {
      writePNG(diffMinimal.diffPNG, diffMinimalPNGPath);
    }
    if (!diffMinimalLegacy.diffPNG) {
      console.error(`Screenshot Error in ${testName}, minimal`);
    } else {
      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();
});
