// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as path from 'path';
import * as vm from 'vm';
import * as fs from 'fs/promises';

import * as esbuild from 'esbuild';
import * as oniguruma from 'oniguruma';
import peggy from 'peggy'; // not esm
import glob from 'glob';

/// processes peggy .pegjs files --> to js (esm) source
export const peggyPlugin = {
  name: 'peggy',
  setup(build) {
    build.onLoad({filter: /.pegjs$/}, async (args) => {
      let pegSource = await fs.readFile(args.path, 'utf8');
      return {
        contents: peggy.generate(pegSource, {output: 'source', format: 'es'}),
        loader: 'js',
      }
    });
  },
}

/// processes syntax-generating scripts to equivalent json files
export const syntaxPlugin = {
  name: 'syntax',
  setup(build) {
    build.onResolve({filter: /^syntax\/.+$/}, async (args) => {
      let lang = path.basename(args.path);
      // resolve pseudo-imports to json file names, so that we write the
      // correct file names, but keep the base language name around for onLoad
      return {path: `syntax/${lang}.tmLanguage.json`, namespace: 'syntax', pluginData: {lang: lang}};
    });

    build.onLoad({filter: /./, namespace: 'syntax'}, async (args) => {
      // first, load & compile the script from ts to js
      const srcFile = path.join("syntax", `${args.pluginData.lang}.ts`);
      let tsContents = await fs.readFile(srcFile, 'utf8');
      let jsContents = await build.esbuild.transform(
        tsContents,
        {
          loader: 'ts',
          platform: 'node',
          target: 'node18',
          format: 'cjs',
        });

      // then, execute the script
      const scr = new vm.Script(jsContents.code);
      const modRes = {
        module: {exports: {}},
        require: (name) => {
          if (name === 'oniguruma') {
            return oniguruma;
          } else {
            throw new Error(`unknown syntax script import ${name}`);
          }
        },
      };
      const ctx = vm.createContext(modRes);
      scr.runInContext(ctx);

      // finally, return the results of the script (a blob of json)
      return {
        contents: JSON.stringify(modRes.module.exports.default),
        loader: 'copy',
        watchFiles: [srcFile],
      };
    });
  }
};

/// locates and bundles all test files
export const testsPlugin = {
  name: 'tests',
  setup(build) {
    build.onResolve({filter: /^all-tests$/}, (args) => {
      return {path: './all-tests.js', namespace: 'tests'};
    });
    build.onLoad({filter: /./, namespace: 'tests'}, async (args) => {
      const files = await allTests();
      return {
        contents: files.map((file) => `import '${file}';\n`).join(""),
        loader: 'js',
        resolveDir: '.',
        // we *may* need to make this watchDirs for adding tests, but stick
        // with files for now
        watchFiles: files,
      };
    });
  },
}

/// finds all syntax files as `syntax/${name}` imports
export async function allSyntax() {
  return (await fs.readdir('syntax')).
    filter((file) => path.extname(file) === '.ts').
    map((file) => path.basename(file).slice(0, -3)).
    map((name) => `syntax/${name}`);
}

/// finds all tests in this project
function allTests() {
  return new Promise((resolve, reject) => {
    glob('./{src,webviews}/**/*.test.ts', (err, files) => {
      if (err) {
        reject(err);
        return;
      }

      resolve(files);
    });
  });
}

/// formats output for running in vscode
export function formatMachineOutput({errors, warnings}, name) {
  return [
    ...(errors ?? []).map((err) => formatMessageForMachine(err, 'error', name)),
    ...(warnings ?? []).map((warning) => formatMessageForMachine(warning, 'warning', name)),
  ].join("\n");
}

/// formats a single esbuild message for machine output
function formatMessageForMachine(msg, kind, name) {
  // column is 0-based, vscode wants it 1-based
  return `${msg.location.file}(${msg.location.line},${msg.location.column+1}):${kind}:[${name}] ${msg.text}`;
}

/// makes a watch that prints out machine-readable error messages
export function makeWatch(name) {
  if (process.argv.length === 3 && process.argv[2] === 'watch') {
    const isMachine = process.env.MACHINE === 'true';
    if (isMachine) {
      return {
        onRebuild(error, result) {
          // TODO(fxbug.dev/106861): to use this with vscode, we'd need to have
          // `watch start` and `watch end` lines, but because builds work in
          // parallel, this would mean that we couldn't use the built-in watch
          // mechanism of esbuild, and would have to build something custom
          // on the incremental API.
          if (error) {
            const out = formatMachineOutput(error, name);
            if (out) console.error(out);
          }
          else {
            const out = formatMachineOutput(result, name);
            if (out) console.log(out);
          }
        },
      };
    } else {
      return true;
    }
  } else {
    return false;
  }
}

/// formats esbuild results as test XML
export function resultsToXML(results) {
  const formatMessage = (kind, msg) => {
    const tag = kind === 'error' ? 'error' : 'failure';
    return `<${tag} message="${msg.text.replace(/"/g, '&quot;')}">
  <![CDATA[${esbuild.formatMessagesSync([msg], {color: false, kind})}]]>
</${tag}>
`;
  };
  let cases = results.
    map(([name, {errors, warnings}]) => {
      return `    <testcase name="${name}" status="run" result="completed">
      ${errors.map((msg) => formatMessage('error', msg))}
      ${warnings.map((msg) => formatMessage('warning', msg))}
    </testcase>`;
    });

  const numErrs = results.filter(([_n, {errors}]) => errors.length !== 0).length;
  const numWarns = results.filter(([_n, {warnings}]) => warnings.length !== 0).length;
  return `<testsuites>
  <testsuite name="esbuild" tests="${results.length}" errors="${numErrs}" failures="${numWarns}">
${cases.join("\n")}
  </testsuite>
</testsuites>`;
}
