// 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 esbuild from 'esbuild';
import * as fs from 'fs/promises';

import {
  peggyPlugin, syntaxPlugin, testsPlugin, generateFlags,
  allSyntax, formatMachineOutput, makeWatch, resultsToXML
} from './build-helpers.mjs';

/// determines if we generate sourcemaps & such
const IS_DEV = process.env.NODE_ENV !== 'production';
if (process.argv.length > 3 || (process.argv.length == 3 && process.argv[2] !== 'watch')) {
  console.error("usage: node build.mjs [watch]");
  console.error(`(saw "${process.argv}")`);
}
const IS_MACHINE = process.env.MACHINE === 'true';

const logLevel = IS_MACHINE ? 'silent' : undefined;

// our configs
//
// notice that we catch errors -- we don't want to bail the entire script if
// we fail, since we want to be able to convert to test xml

let syntaxFiles = await allSyntax();
const hostCfg = esbuild.build({
  bundle: true,
  platform: 'node',
  format: 'cjs',
  entryPoints: ['./src/extension.ts'],
  outfile: 'dist/extension.js',
  external: ['vscode'],
  sourcemap: IS_DEV ? 'linked' : '',
  minify: !IS_DEV,
  watch: makeWatch("host"),
  logLevel,
}).catch((res) => res);

const resCfg = esbuild.build({
  entryPoints: syntaxFiles,
  entryNames: 'resources/[dir]/[name]',
  plugins: [syntaxPlugin],
  outbase: '.',
  outdir: 'dist',
  watch: makeWatch("res"),
  logLevel,
}).catch((res) => res);

const viewCfg = esbuild.build({
  bundle: true,
  platform: 'browser',
  entryPoints: ['./webviews/logging'],
  outdir: 'dist',
  outbase: '.',
  plugins: [peggyPlugin],
  entryNames: '[dir]-[name]',
  sourcemap: IS_DEV ? 'linked' : '',
  loader: {
    '.ttf': 'file',
    '.css': 'text',
  },
  minify: !IS_DEV,
  watch: makeWatch("view"),
  logLevel,
}).catch((res) => res);

// Export the logging view component as a re-usable UI module that can be used
// by any external project.
const viewModuleCfg = esbuild.build({
  bundle: true,
  platform: 'node',
  entryPoints: ['./webviews/logging/module.ts'],
  outdir: 'dist',
  outbase: '.',
  plugins: [peggyPlugin],
  entryNames: '[dir]-[name]',
  sourcemap: IS_DEV ? 'linked' : '',
  loader: {
    '.ttf': 'file',
    '.css': 'text',
  },
  minify: !IS_DEV,
  watch: makeWatch("view"),
  logLevel,
}).catch((res) => res);


const testCfg = esbuild.build({
  bundle: true,
  platform: 'node',
  external: [
    'vscode',
    'canvas' /* conditional import, not in use */,
    'mocha' /* does funky things */,
    'jsdom' /* does funky things */,
    'vscode-oniguruma', /* we import files from it via require.resolve */
  ],
  entryPoints: ['./src/test/run_test.ts', './src/test/suite/index.ts', 'all-tests'],
  outdir: 'test-dist',
  sourcemap: true,
  plugins: [peggyPlugin, testsPlugin('./src/**/*.test.ts')],
  watch: makeWatch("test"),
  logLevel,
}).catch((res) => res);

const webviewTestCfg = (async () => {
  return await esbuild.build({
    bundle: true,
    platform: 'browser',
    entryPoints: ['all-tests'],
    external: [],
    outdir: 'test-webview-dist',
    sourcemap: true,
    loader: {
      '.ttf': 'file',
    },
    plugins: [peggyPlugin, testsPlugin('./webviews/**/*.test.ts')],
    watch: makeWatch('test-webview'),
    logLevel,
  });
})();

// awaiting will print the results, but we want the results as objects (mapped
// to their names) in case we need to write test xml for CI
let mainPromises = [
  ['host', hostCfg],
  ['view', viewCfg],
  ['viewModule', viewModuleCfg],
  ['resources', resCfg],
  ['test', testCfg],
  ['webview-test', webviewTestCfg]
];
let resultsWithoutName = await Promise.all(mainPromises.map(([_name, prom]) => prom));

// do the flags plugin afterwards, because it messes with package.json and
// doing it in paralell can cause issues.  It doesn't generate any files,
// so it's not gonna cause bundling issues to do it later.
let flagsRes = await generateFlags()
  .then(() => ({errors: [], warnings: []}))
  .catch((res) => {
    let wrapper = new Error("unable to convert flags to settings");
    wrapper.errors = [{
      text: res.toString(),
      detail: res,
    }];
    wrapper.warnings = [];
    return wrapper;
  });

// write the results as test XML if on CI
let results = mainPromises.map(([name, _p], i) => [name, resultsWithoutName[i]]);
results.push(['flags', flagsRes]);

if (!!process.env.BUILD_XML_OUTPUT) {
  console.debug('writing build results to test XML');
  await fs.writeFile(process.env.BUILD_XML_OUTPUT, resultsToXML(results));
}
if (IS_MACHINE) {
  for (const [name, res] of results) {
    const out = formatMachineOutput(res, name);
    if (!out) continue;

    if (res instanceof Error) { console.error(out); }
    else { console.log(out); }
  }
}

// finally, check if we need to exit as unsuccesful
// (since swallow exceptions above)
if (results.some(([_n, res]) => res instanceof Error)) {
  process.exit(1);
}
