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

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],
  ['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);
}
