// Copyright (C) 2021 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This script takes care of:
// - The build process for the whole UI and the chrome extension.
// - The HTTP dev-server with live-reload capabilities.
// The reason why this is a hand-rolled script rather than a conventional build
// system is keeping incremental build fast and maintaining the set of
// dependencies contained.
// The only way to keep incremental build fast (i.e. O(seconds) for the
// edit-one-line -> reload html cycles) is to run both the TypeScript compiler
// and the rollup bundler in --watch mode. Any other attempt, leads to O(10s)
// incremental-build times.
// This script allows mixing build tools that support --watch mode (tsc and
// rollup) and auto-triggering-on-file-change rules via fs.watch.
// When invoked without any argument (e.g., for production builds), this script
// just runs all the build tasks serially. It doesn't to do any mtime-based
// check, it always re-runs all the tasks.
// When invoked with --watch, it mounts a pipeline of tasks based on fs.watch
// and runs them together with tsc --watch and rollup --watch.
// The output directory structure is carefully crafted so that any change to UI
// sources causes cascading triggers of the next steps.
// The overall build graph looks as follows:
// +----------------+      +-----------------------------+
// | protos/*.proto |----->| pbjs out/tsc/gen/protos.js  |--+
// +----------------+      +-----------------------------+  |
//                         +-----------------------------+  |
//                         | pbts out/tsc/gen/protos.d.ts|<-+
//                         +-----------------------------+
//                             |
//                             V      +-------------------------+
// +---------+              +-----+   |  out/tsc/frontend/*.js  |
// | ui/*.ts |------------->| tsc |-> +-------------------------+   +--------+
// +---------+              +-----+   | out/tsc/controller/*.js |-->| rollup |
//                            ^       +-------------------------+   +--------+
//                +------------+      |   out/tsc/engine/*.js   |       |
// +-----------+  |*.wasm.js   |      +-------------------------+       |
// |ninja *.cc |->|*.wasm.d.ts |                                        |
// +-----------+  |*.wasm      |-----------------+                      |
//                +------------+                 |                      |
//                                               V                      V
// +-----------+  +------+    +------------------------------------------------+
// | ui/*.scss |->| scss |--->|              Final out/dist/ dir               |
// +-----------+  +------+    +------------------------------------------------+
// +----------------------+   | +----------+ +---------+ +--------------------+|
// | src/assets/*.png     |   | | assets/  | |*.wasm.js| | frontend_bundle.js ||
// +----------------------+   | |  *.css   | |*.wasm   | +--------------------+|
// | buildtools/typefaces |-->| |  *.png   | +---------+ |  engine_bundle.js  ||
// +----------------------+   | |  *.woff2 |             +--------------------+|
// | buildtools/legacy_tv |   | |  tv.html |             |traceconv_bundle.js ||
// +----------------------+   | +----------+             +--------------------+|
//                            +------------------------------------------------+

import argparse from 'argparse';
import childProcess from 'node:child_process';
import crypto from 'node:crypto';
import fs from 'node:fs';
import http from 'node:http';
import path from 'node:path';
import zlib from 'node:zlib';
import {fileURLToPath} from 'node:url';

const pjoin = path.join;
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const ROOT_DIR = path.dirname(__dirname); // The repo root.
const VERSION_SCRIPT = pjoin(ROOT_DIR, 'tools/write_version_header.py');
const DEFAULT_PORT = 10000;

const cfg = {
  minifyJs: '',
  noSourceMaps: false,
  noTreeshake: false,
  watch: false,
  verbose: false,
  debug: false,
  bigtrace: false,
  engineBench: false,
  startHttpServer: false,
  httpServerListenHost: '127.0.0.1',
  httpServerListenPort: undefined,
  onlyWasmMemory64: false,
  wasmModules: [],
  crossOriginIsolation: false,
  testFilter: '',
  noOverrideGnArgs: false,

  // The fields below will be changed by main() after cmdline parsing.
  // Directory structure:
  // out/xxx/    -> outDir         : Root build dir, for both ninja/wasm and UI.
  //   ui/       -> outUiDir       : UI dir. All outputs from this script.
  //    tsc/     -> outTscDir      : Transpiled .ts -> .js.
  //      gen/   -> outGenDir      : Auto-generated .ts/.js (e.g. protos).
  //    dist/    -> outDistRootDir : Only index.html and service_worker.js
  //      v1.2/  -> outDistDir     : JS bundles and assets
  //    chrome_extension/          : Chrome extension.
  outDir: pjoin(ROOT_DIR, 'out/ui'),
  version: '', // v1.2.3, derived from the CHANGELOG + git.
  outUiDir: '',
  outUiTestArtifactsDir: '',
  outDistRootDir: '',
  outTscDir: '',
  outGenDir: '',
  outDistDir: '',
  outExtDir: '',
  outBigtraceDistDir: '',
  outOpenPerfettoTraceDistDir: '',
  lockFile: '',
};

const RULES = [
  {r: /ui\/src\/assets\/index.html/, f: copyIndexHtml},
  {r: /ui\/src\/assets\/bigtrace.html/, f: copyBigtraceHtml},
  {r: /ui\/src\/open_perfetto_trace\/index.html/, f: copyOpenPerfettoTraceHtml},
  // engine_bench page; no-op without --enable-engine-bench.
  {r: /ui\/src\/engine_bench\/bench\.html$/, f: copyEngineBenchHtml},
  {r: /ui\/src\/assets\/((.*)[.]png)/, f: copyAssets},
  {r: /ui\/src\/assets\/(data_explorer\/base-page\.json)/, f: copyAssets},
  {r: /ui\/src\/assets\/(data_explorer\/examples\/(.*)[.]json)/, f: copyAssets},
  {r: /ui\/src\/assets\/(data_explorer\/node_info\/(.*)[.]md)/, f: copyAssets},
  {r: /buildtools\/typefaces\/(.+[.]woff2)/, f: copyAssets},
  {r: /buildtools\/catapult_trace_viewer\/(.+(js|html))/, f: copyAssets},
  {r: /ui\/src\/chrome_extension\/.*/, f: copyExtensionAssets},
  {r: /.*\/dist\/.+\/(?!manifest\.json).*/, f: genServiceWorkerManifestJson},
  {r: /.*\/dist\/.*[.](js|html|css|wasm)$/, f: notifyLiveServer},
];

const tasks = [];
let tasksTot = 0;
let tasksRan = 0;
const httpWatches = [];
const tStart = performance.now();
const subprocesses = [];
const LIVE_SERVER_DEBOUNCE_MS = 250;
let liveServerDebounceTimerId = 0;
const notifyLiveServerPendingFiles = new Set();

// Loads ~/.config/perfetto/ui-dev-server.env and injects any KEY=VALUE pairs
// into process.env, without overriding variables already set in the environment.
function loadDevServerEnvFile() {
  const home = process.env.HOME || process.env.USERPROFILE || '';
  const envFile = path.join(home, '.config', 'perfetto', 'ui-dev-server.env');
  let content;
  try {
    content = fs.readFileSync(envFile, 'utf8');
  } catch (e) {
    return; // File absent or unreadable — not an error.
  }
  for (const line of content.split('\n')) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith('#')) continue;
    const eqIdx = trimmed.indexOf('=');
    if (eqIdx < 0) continue;
    const key = trimmed.slice(0, eqIdx).trim();
    const value = trimmed.slice(eqIdx + 1).trim();
    if (!(key in process.env)) process.env[key] = value;
  }
}

async function main() {
  const parser = new argparse.ArgumentParser({
    formatter_class: argparse.RawDescriptionHelpFormatter,
    epilog: `
Env-var overrides:
  Any flag can be set via a PERFETTO_UI_<FLAG> environment variable,
  where <FLAG> is the flag name uppercased with hyphens replaced by
  underscores. Boolean flags are activated by "1" or "true". CLI flags
  always take precedence over environment variables.

  Examples:
    PERFETTO_UI_SERVE_HOST=0.0.0.0
    PERFETTO_UI_SERVE_PORT=10000
    PERFETTO_UI_NO_BUILD=1
    PERFETTO_UI_TITLE=my-instance

  Defaults can also be persisted in:
    ~/.config/perfetto/ui-dev-server.env
  (one KEY=VALUE per line, # comments supported). Shell env vars take
  precedence over the file.
`,
  });
  parser.add_argument('--out', {help: 'Output directory'});
  parser.add_argument('--minify-js', {
    help: 'Minify js files',
    choices: ['preserve_comments', 'all'],
  });
  parser.add_argument('--no-source-maps', {
    action: 'store_true',
    help: 'Skip source map generation entirely',
  });
  parser.add_argument('--no-treeshake', {
    action: 'store_true',
    help: 'Disable rollup tree-shaking (much faster incremental rebuilds)',
  });
  parser.add_argument('--watch', '-w', {action: 'store_true'});
  parser.add_argument('--serve', '-s', {action: 'store_true'});
  parser.add_argument('--serve-host', {help: '--serve bind host'});
  parser.add_argument('--serve-port', {help: '--serve bind port', type: 'int'});
  parser.add_argument('--verbose', '-v', {action: 'store_true'});
  parser.add_argument('--no-build', '-n', {action: 'store_true'});
  parser.add_argument('--no-wasm', '-W', {action: 'store_true'});
  parser.add_argument('--only-wasm-memory64', {action: 'store_true'});
  parser.add_argument('--run-unittests', '-t', {action: 'store_true'});
  parser.add_argument('--debug', '-d', {action: 'store_true'});
  parser.add_argument('--bigtrace', {action: 'store_true'});
  parser.add_argument('--enable-engine-bench', {
    action: 'store_true',
    help: 'Build the engine startup benchmark page (engine_bench.html) and ' +
          'its dedicated worker bundle. Off by default.',
  });
  parser.add_argument('--open-perfetto-trace', {action: 'store_true'});
  parser.add_argument('--interactive', '-i', {action: 'store_true'});
  parser.add_argument('--rebaseline', '-r', {action: 'store_true'});
  parser.add_argument('--no-depscheck', {action: 'store_true'});
  parser.add_argument('--cross-origin-isolation', {action: 'store_true'});
  parser.add_argument('--test-filter', '-f', {
    help: "filter Jest tests by regex, e.g. 'chrome_render'",
  });
  parser.add_argument('--no-override-gn-args', {action: 'store_true'});
  parser.add_argument('--typecheck', {
    action: 'store_true',
    help: 'Only type-check (tsc --noEmit), skip bundling',
  });
  parser.add_argument('--title', {
    help: 'Override the page title (useful for distinguishing multiple instances)',
  });

  // Load ~/.config/perfetto/ui-dev-server.env defaults, then map any
  // PERFETTO_UI_* env vars to synthetic argv entries prepended before the
  // real argv so that explicit CLI flags always take precedence.
  loadDevServerEnvFile();
  const envPrefix = 'PERFETTO_UI_';
  const syntheticArgv = [];
  for (const [key, val] of Object.entries(process.env)) {
    if (!key.startsWith(envPrefix)) continue;
    const flag =
      '--' + key.slice(envPrefix.length).toLowerCase().replace(/_/g, '-');
    const action = parser._actions.find((a) =>
      (a.option_strings || []).includes(flag),
    );
    if (!action) continue;
    const isBoolFlag = action.nargs === 0;
    if (isBoolFlag) {
      if (val === '1' || val.toLowerCase() === 'true') syntheticArgv.push(flag);
    } else {
      syntheticArgv.push(`${flag}=${val}`);
    }
  }
  const args = parser.parse_args([...syntheticArgv, ...process.argv.slice(2)]);
  const clean = !args.no_build;
  cfg.outDir = path.resolve(ensureDir(args.out || cfg.outDir));
  cfg.lockFile = pjoin(cfg.outDir, 'watch.lock');

  // Only create the build lock if we are actually going to build If --no-build
  // is passed, we can run simultaneoushy without worrying about the build lock,
  // since we won't be writing to the output directories.
  if (!args.no_build) {
    prepareBuildLock();
  }

  cfg.outUiDir = ensureDir(pjoin(cfg.outDir, 'ui'), clean);
  cfg.outUiTestArtifactsDir = ensureDir(pjoin(cfg.outDir, 'ui-test-artifacts'));
  cfg.outExtDir = ensureDir(pjoin(cfg.outUiDir, 'chrome_extension'));
  cfg.outDistRootDir = ensureDir(pjoin(cfg.outUiDir, 'dist'));
  const proc = exec('python3', [VERSION_SCRIPT, '--stdout'], {stdout: 'pipe'});
  cfg.version = proc.stdout.toString().trim();
  cfg.outDistDir = ensureDir(pjoin(cfg.outDistRootDir, cfg.version));
  cfg.outTscDir = ensureDir(pjoin(cfg.outUiDir, 'tsc'));
  cfg.outGenDir = ensureDir(pjoin(cfg.outUiDir, 'tsc/gen'));
  cfg.testFilter = args.test_filter || '';
  cfg.watch = !!args.watch;
  cfg.verbose = !!args.verbose;
  cfg.debug = !!args.debug;
  cfg.bigtrace = !!args.bigtrace;
  cfg.engineBench = !!args.enable_engine_bench;
  cfg.openPerfettoTrace = !!args.open_perfetto_trace;
  cfg.startHttpServer = args.serve;
  cfg.noOverrideGnArgs = !!args.no_override_gn_args;
  if (args.minify_js) {
    cfg.minifyJs = args.minify_js;
  }
  cfg.noSourceMaps = !!args.no_source_maps;
  cfg.noTreeshake = !!args.no_treeshake;
  if (args.bigtrace) {
    cfg.outBigtraceDistDir = ensureDir(pjoin(cfg.outDistDir, 'bigtrace'));
  }
  if (cfg.openPerfettoTrace) {
    cfg.outOpenPerfettoTraceDistDir = ensureDir(
      pjoin(cfg.outDistRootDir, 'open_perfetto_trace'),
    );
  }
  if (args.serve_host) {
    cfg.httpServerListenHost = args.serve_host;
  }
  if (args.serve_port) {
    cfg.httpServerListenPort = args.serve_port;
  }
  if (args.interactive) {
    process.env.PERFETTO_UI_TESTS_INTERACTIVE = '1';
  }
  if (args.rebaseline) {
    process.env.PERFETTO_UI_TESTS_REBASELINE = '1';
  }
  if (args.cross_origin_isolation) {
    cfg.crossOriginIsolation = true;
  }
  cfg.check = !!args.typecheck;
  cfg.onlyWasmMemory64 = !!args.only_wasm_memory64;
  cfg.titleOverride = args.title || '';
  cfg.wasmModules = ['traceconv', 'proto_utils', 'trace_processor_memory64'];
  if (!cfg.onlyWasmMemory64) {
    cfg.wasmModules.push('trace_processor');
  }

  function terminateChildProcesses() {
    for (const proc of subprocesses) {
      console.log(`Terminating child process with PID ${proc.pid}`);
      proc.kill(); // SIGTERM is the default
    }
  }

  // Called whenever the process exits due to:
  // 1. The JS loop running out of work - (normal exit or uncaught exception).
  // 2. Manually calling process.exit().
  process.on('exit', () => {
    terminateChildProcesses();
  });

  // Register signal handlers for the usual termination signals. Only handle
  // once per signal so we can then call process.kill(sig) in order for the
  // process to exit with the correct exit code.
  for (const sig of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
    process.once(sig, () => {
      terminateChildProcesses();
      process.kill(process.pid, sig);
    });
  }

  if (!args.no_depscheck) {
    // Check that deps are current before starting.
    const installBuildDeps = pjoin(ROOT_DIR, 'tools/install-build-deps');
    const checkDepsPath = pjoin(cfg.outDir, '.check_deps');
    let args = [installBuildDeps, `--check-only=${checkDepsPath}`, '--ui'];

    if (process.platform === 'darwin') {
      const result = childProcess.spawnSync('arch', ['-arm64', 'true']);
      const isArm64Capable = result.status === 0;
      if (isArm64Capable) {
        const archArgs = ['arch', '-arch', 'arm64'];
        args = archArgs.concat(args);
      }
    }
    const cmd = args.shift();
    exec(cmd, args);
  }

  console.log('Entering', cfg.outDir);
  process.chdir(cfg.outDir);

  // Enqueue empty task. This is needed only for --no-build --serve. The HTTP
  // server is started when the task queue reaches quiescence, but it takes at
  // least one task for that.
  addTask(() => {});

  if (args.no_build && cfg.check) {
    // --no-build --typecheck: just run tsc --noEmit assuming out dir exists.
    const tsProjects = ['ui', 'ui/src/service_worker'];
    if (cfg.bigtrace) tsProjects.push('ui/src/bigtrace');
    if (cfg.openPerfettoTrace) tsProjects.push('ui/src/open_perfetto_trace');
    for (const prj of tsProjects) {
      transpileTsProject(prj, {noEmit: true});
    }
  } else if (!args.no_build) {
    updateSymlinks(); // Links //ui/out -> //out/xxx/ui/

    buildWasm(args.no_wasm);
    copySyntaqliteRuntime();
    scanDir('ui/src/assets');
    scanDir('ui/src/chrome_extension');
    scanDir('buildtools/typefaces');
    scanDir('buildtools/catapult_trace_viewer');
    compileProtos();
    genVersion();
    generateStdlibDocs();

    const tsProjects = ['ui', 'ui/src/service_worker'];
    if (cfg.bigtrace) tsProjects.push('ui/src/bigtrace');
    if (cfg.openPerfettoTrace) {
      scanDir('ui/src/open_perfetto_trace');
      tsProjects.push('ui/src/open_perfetto_trace');
    }
    if (cfg.engineBench) {
      scanDir('ui/src/engine_bench');
    }

    if (cfg.check) {
      for (const prj of tsProjects) {
        transpileTsProject(prj, {noEmit: true});
      }
    } else {
      // Vite owns TS transpile + bundling. tsc is invoked separately purely
      // for type checking. In non-watch builds it runs synchronously and a
      // type error fails the build. In watch mode tsc --watch runs async in
      // the background and prints errors without killing the build.
      for (const prj of tsProjects) {
        if (cfg.watch) {
          transpileTsProject(prj, {
            watch: true,
            noEmit: true,
            noErrCheck: true,
          });
        } else {
          transpileTsProject(prj, {noEmit: true});
        }
      }
      runVite();
      genServiceWorkerManifestJson();

      // Watches the /dist. When changed:
      // - Notifies the HTTP live reload clients.
      // - Regenerates the ServiceWorker file map.
      scanDir(cfg.outDistRootDir);
    }
  }

  // We should enter the loop only in watch mode, where tsc and rollup are
  // asynchronous because they run in watch mode.
  if (args.no_build && !isDistComplete()) {
    console.log('No build was requested, but artifacts are not available.');
    console.log('In case of execution error, re-run without --no-build.');
  }
  if (!args.no_build && !cfg.check) {
    const tStart = performance.now();
    while (!isDistComplete()) {
      const secs = Math.ceil((performance.now() - tStart) / 1000);
      process.stdout.write(
        `\t\tWaiting for first build to complete... ${secs} s\r`,
      );
      await new Promise((r) => setTimeout(r, 500));
    }
  }
  if (cfg.watch) console.log('\nFirst build completed!');

  if (cfg.startHttpServer) {
    if (cfg.watch) {
      await startViteDevServer();
    } else {
      startServer();
    }
  }
  if (args.run_unittests) {
    runTests();
  }
}

// -----------
// Build rules
// -----------

function runTests() {
  // Vitest reads ui/vitest.config.mjs by default. ts is transpiled on the fly
  // by Vite, so there's no tsc-emitted .js layer involved.
  const args = [
    cfg.watch ? 'watch' : 'run',
    '--config',
    pjoin(ROOT_DIR, 'ui/vitest.config.mjs'),
  ];
  if (cfg.testFilter.length > 0) {
    args.push('-t', cfg.testFilter);
  }
  if (cfg.watch) {
    addTask(execModule, ['vitest', args, {async: true}]);
  } else {
    addTask(execModule, ['vitest', args]);
  }
}

function cpHtml(src, filename) {
  let html = fs.readFileSync(src).toString();
  // First copy the html as-is into the dist/v1.2.3/ directory. This is
  // only used for archival purporses, so one can open
  // ui.perfetto.dev/v1.2.3/ to skip the auto-update and channel logic.
  fs.writeFileSync(pjoin(cfg.outDistDir, filename), html);

  // Then copy it into the dist/ root by patching the version code.
  // TODO(primiano): in next CLs, this script should take a
  // --release_map=xxx.json argument, to populate this with multiple channels.
  const versionMap = JSON.stringify({stable: cfg.version});
  const bodyRegex = /data-perfetto_version='[^']*'/;
  html = html.replace(bodyRegex, `data-perfetto_version='${versionMap}'`);

  // If --title was provided, patch the page title. Useful when running
  // multiple dev server instances to distinguish browser tabs.
  if (cfg.titleOverride) {
    html = html.replace(
      /<title>[^<]*<\/title>/,
      `<title>${cfg.titleOverride}</title>`,
    );
  }

  fs.writeFileSync(pjoin(cfg.outDistRootDir, filename), html);
}

function copyIndexHtml(src) {
  addTask(cpHtml, [src, 'index.html']);
}

function copyBigtraceHtml(src) {
  if (cfg.bigtrace) {
    addTask(cpHtml, [src, 'bigtrace.html']);
  }
}

function copyOpenPerfettoTraceHtml(src) {
  if (cfg.openPerfettoTrace) {
    addTask(cp, [src, pjoin(cfg.outOpenPerfettoTraceDistDir, 'index.html')]);
  }
}

function copyEngineBenchHtml(src) {
  if (!cfg.engineBench) return;
  // Goes next to engine_bench_bundle.js so its relative <script> resolves.
  addTask(cp, [src, pjoin(cfg.outDistDir, 'engine_bench.html')]);
  addTask(makeEngineBenchRedirect, []);
}

function makeEngineBenchRedirect() {
  const target = `${cfg.version}/engine_bench.html`;
  // Redirect via JS so the bench knob query string is preserved.
  const html =
    '<!DOCTYPE html><meta charset="utf-8">' +
    '<title>Perfetto engine bench (redirect)</title>' +
    `<script>location.replace(${JSON.stringify(target)} + location.search + ` +
    'location.hash);</script>' +
    `<noscript><meta http-equiv="refresh" content="0; url=${target}">` +
    `<p>Redirecting to <a href="${target}">${target}</a>.</p></noscript>\n`;
  fs.writeFileSync(pjoin(cfg.outDistRootDir, 'engine_bench.html'), html);
}

function copyAssets(src, dst) {
  addTask(cp, [src, pjoin(cfg.outDistDir, 'assets', dst)]);
  if (cfg.bigtrace) {
    addTask(cp, [src, pjoin(cfg.outBigtraceDistDir, 'assets', dst)]);
  }
}

function copyUiTestArtifactsAssets(src, dst) {
  addTask(cp, [src, pjoin(cfg.outUiTestArtifactsDir, dst)]);
}

function compileProtos() {
  const dstJs = pjoin(cfg.outGenDir, 'protos.js');
  const dstTs = pjoin(cfg.outGenDir, 'protos.d.ts');
  const inputs = [
    'protos/perfetto/ipc/consumer_port.proto',
    'protos/perfetto/ipc/wire_protocol.proto',
    'protos/perfetto/trace/perfetto/perfetto_metatrace.proto',
    'protos/perfetto/perfetto_sql/structured_query.proto',
    'protos/perfetto/trace_processor/trace_processor.proto',
  ];
  // Can't put --no-comments here - The comments are load bearing for
  // the pbts invocation which follows.
  const pbjsArgs = [
    '--no-beautify',
    '--force-number',
    '--no-delimited',
    '--no-verify',
    '-t',
    'static-module',
    '-w',
    'es6',
    '-p',
    ROOT_DIR,
    '-o',
    dstJs,
  ].concat(inputs);
  addTask(execModule, ['pbjs', pbjsArgs]);

  // Note: If you are looking into slowness of pbts it is not pbts
  // itself that is slow. It invokes jsdoc to parse the comments out of
  // the |dstJs| with https://github.com/hegemonic/catharsis which is
  // pinning a CPU core the whole time.
  const pbtsArgs = ['--no-comments', '-p', ROOT_DIR, '-o', dstTs, dstJs];
  addTask(execModule, ['pbts', pbtsArgs]);
}

// Generates a .ts source that defines the VERSION and SCM_REVISION constants.
function genVersion() {
  const cmd = 'python3';
  const args = [
    VERSION_SCRIPT,
    '--ts_out',
    pjoin(cfg.outGenDir, 'perfetto_version.ts'),
  ];
  addTask(exec, [cmd, args]);
}

function generateStdlibDocs() {
  const cmd = pjoin(ROOT_DIR, 'tools/gen_stdlib_docs_json.py');
  const stdlibDir = pjoin(ROOT_DIR, 'src/trace_processor/perfetto_sql/stdlib');

  const stdlibFiles = listFilesRecursive(stdlibDir).filter(
    (filePath) => path.extname(filePath) === '.sql',
  );

  addTask(exec, [
    cmd,
    [
      '--json-out',
      pjoin(cfg.outDistDir, 'stdlib_docs.json'),
      '--minify',
      ...stdlibFiles,
    ],
  ]);
}

function updateSymlinks() {
  // /ui/out -> /out/ui.
  mklink(cfg.outUiDir, pjoin(ROOT_DIR, 'ui/out'));

  // /ui/src/gen -> /out/ui/ui/tsc/gen)
  mklink(cfg.outGenDir, pjoin(ROOT_DIR, 'ui/src/gen'));

  // /out/ui/test/data -> /test/data (For UI tests).
  mklink(
    pjoin(ROOT_DIR, 'test/data'),
    pjoin(ensureDir(pjoin(cfg.outDir, 'test')), 'data'),
  );

  // Creates a out/dist_version -> out/dist/v1.2.3 symlink, so rollup config
  // can point to that without having to know the current version number.
  mklink(
    path.relative(cfg.outUiDir, cfg.outDistDir),
    pjoin(cfg.outUiDir, 'dist_version'),
  );

  mklink(
    pjoin(ROOT_DIR, 'ui/node_modules'),
    pjoin(cfg.outTscDir, 'node_modules'),
  );
}

// Invokes ninja for building the {trace_processor, traceconv} Wasm modules.
// It copies the .wasm directly into the out/dist/ dir, and the .js/.ts into
// out/tsc/, so the typescript compiler and the bundler can pick them up.
function buildWasm(skipWasmBuild) {
  if (!skipWasmBuild) {
    if (!cfg.noOverrideGnArgs) {
      let gnVars = `is_debug=${cfg.debug}`;
      if (childProcess.spawnSync('which', ['ccache']).status === 0) {
        gnVars += ` cc_wrapper="ccache"`;
      }
      const gnArgs = ['gen', `--args=${gnVars}`, cfg.outDir];
      addTask(exec, [pjoin(ROOT_DIR, 'tools/gn'), gnArgs]);
    }
    const ninjaArgs = ['-C', cfg.outDir];
    ninjaArgs.push(...cfg.wasmModules.map((x) => `${x}_wasm`));
    addTask(exec, [pjoin(ROOT_DIR, 'tools/ninja'), ninjaArgs]);
  }

  for (const wasmMod of cfg.wasmModules) {
    const isMem64 = wasmMod.endsWith('_memory64');
    const wasmOutDir = pjoin(cfg.outDir, isMem64 ? 'wasm_memory64' : 'wasm');
    // The .wasm file goes directly into the dist dir (also .map in debug)
    for (const ext of ['.wasm'].concat(cfg.debug ? ['.wasm.map'] : [])) {
      const src = `${wasmOutDir}/${wasmMod}${ext}`;
      addTask(cp, [src, pjoin(cfg.outDistDir, wasmMod + ext)]);
    }
    // The .js / .ts go into intermediates, they will be bundled by rollup.
    for (const ext of ['.js', '.d.ts']) {
      const fname = `${wasmMod}${ext}`;
      addTask(cp, [pjoin(wasmOutDir, fname), pjoin(cfg.outGenDir, fname)]);
    }
  }
}

function copySyntaqliteRuntime() {
  const srcDir = pjoin(ROOT_DIR, 'ui/node_modules/syntaqlite/wasm');
  const dstDir = pjoin(cfg.outDistRootDir, 'assets');
  for (const fname of [
    'syntaqlite-runtime.js',
    'syntaqlite-runtime.wasm',
    'syntaqlite-sqlite.wasm',
  ]) {
    addTask(cp, [pjoin(srcDir, fname), pjoin(dstDir, fname)]);
  }
  addTask(buildSyntaqlitePerfettoDialect, []);
}

function getBuildToolsBinDir() {
  function getBinDirName() {
    switch (process.platform) {
      case 'darwin':
        return 'mac';
      case 'linux':
        return 'linux64';
      default:
        throw new Error(`Unsupported platform: ${process.platform}`);
    }
  }

  return pjoin(ROOT_DIR, 'buildtools', getBinDirName());
}

function buildSyntaqlitePerfettoDialect() {
  const buildToolsBinDir = getBuildToolsBinDir();
  const emcc = pjoin(buildToolsBinDir, 'emsdk/emscripten/emcc');
  const src = pjoin(
    ROOT_DIR,
    'src/trace_processor/perfetto_sql/syntaqlite/syntaqlite_perfetto.c',
  );
  const dst = pjoin(cfg.outDistRootDir, 'assets', 'syntaqlite-perfetto.wasm');
  try {
    const srcMtime = fs.statSync(src).mtimeMs;
    const dstMtime = fs.statSync(dst).mtimeMs;
    if (dstMtime >= srcMtime) return;
  } catch (e) {
    /* dst missing → rebuild */
  }
  ensureDir(path.dirname(dst));
  const emConfig = pjoin(ROOT_DIR, 'gn/standalone/.emscripten');
  const prevEmConfig = process.env.EM_CONFIG;
  process.env.EM_CONFIG = emConfig;
  try {
    exec(emcc, [
      '-O2',
      '-sSIDE_MODULE=2',
      '-sEXPORTED_FUNCTIONS=_syntaqlite_perfetto_dialect_template',
      '-o',
      dst,
      src,
    ]);
  } finally {
    if (prevEmConfig === undefined) delete process.env.EM_CONFIG;
    else process.env.EM_CONFIG = prevEmConfig;
  }
}

// This transpiles all the sources (frontend, controller, engine, extension) in
// one go. The only project that has a dedicated invocation is service_worker.
function transpileTsProject(project, options) {
  const args = ['--project', pjoin(ROOT_DIR, project)];
  options = options || {};

  if (options.noEmit) args.push('--noEmit');

  if (options.watch) {
    args.push('--watch', '--preserveWatchOutput');
    addTask(execModule, [
      'tsc',
      args,
      {
        async: true,
        noErrCheck: options.noErrCheck,
      },
    ]);
  } else if (options.noEmit) {
    addTask(execModule, ['tsc', args]);
  } else {
    addTask(execModule, ['tsc', args, {noErrCheck: options.noErrCheck}]);
  }
}

// Runs `vite build` (optionally in --watch mode) to transpile TS and produce
// the {frontend, engine, traceconv}_bundle.js files in cfg.outDistDir. All
// configuration lives in ui/vite.config.mjs; flags are passed via env vars to
// keep parity with the old rollup.config.js conventions.
//
// In watch+serve mode the frontend bundle is replaced by an in-process Vite
// dev server (see startViteDevServer) — workers and the service worker still
// go through `vite build --watch` because they're loaded as separate files by
// `new Worker(assetSrc(...))` / SW registration.
function runVite() {
  const baseEnv = {
    NO_SOURCE_MAPS: cfg.noSourceMaps ? 'true' : '',
    NO_TREESHAKE: cfg.noTreeshake ? 'true' : '',
    MINIFY_JS: cfg.minifyJs || '',
    IS_MEMORY64_ONLY: cfg.onlyWasmMemory64 ? 'true' : '',
  };
  const useDevServer = cfg.watch && cfg.startHttpServer;
  const bundles = ['engine', 'traceconv', 'service_worker', 'chrome_extension'];
  if (!useDevServer) bundles.unshift('frontend');
  if (cfg.bigtrace) bundles.push('bigtrace');
  if (cfg.engineBench) bundles.push('engine_bench', 'engine_bench_worker');
  if (cfg.openPerfettoTrace) bundles.push('open_perfetto_trace');
  for (const bundle of bundles) {
    const args = ['build', '--config', pjoin(ROOT_DIR, 'ui/vite.config.mjs')];
    if (cfg.watch) args.push('--watch');
    if (!cfg.verbose) args.push('--logLevel', 'warn');
    addTask(execModule, [
      'vite',
      args,
      {
        async: cfg.watch,
        env: {...baseEnv, BUNDLE: bundle},
      },
    ]);
  }
}

function genServiceWorkerManifestJson() {
  function makeManifest() {
    const manifest = {resources: {}};
    // When building the subresource manifest skip source maps, the manifest
    // itself and the copy of the index.html which is copied under /v1.2.3/.
    // The root /index.html will be fetched by service_worker.js separately.
    const skipRegex = /(\.map|manifest\.json|index.html)$/;
    walk(
      cfg.outDistDir,
      (absPath) => {
        const contents = fs.readFileSync(absPath);
        const relPath = path.relative(cfg.outDistDir, absPath);
        const b64 = crypto
          .createHash('sha256')
          .update(contents)
          .digest('base64');
        manifest.resources[relPath] = 'sha256-' + b64;
      },
      skipRegex,
    );
    const manifestJson = JSON.stringify(manifest, null, 2);
    fs.writeFileSync(pjoin(cfg.outDistDir, 'manifest.json'), manifestJson);
  }
  addTask(makeManifest, []);
}

// In dev (--watch --serve), Vite owns the user-facing port. It serves the
// frontend entry as native ESM transformed on the fly; everything else
// (wasm, fonts, css, /test/, /v1.2.3/-relative paths) is layered on as
// middleware. The custom HTTP server (startServer) is bypassed.
async function startViteDevServer() {
  // vite.config.mjs reads these at import time; set before createServer().
  if (cfg.onlyWasmMemory64) process.env.IS_MEMORY64_ONLY = 'true';
  if (cfg.noSourceMaps) process.env.NO_SOURCE_MAPS = 'true';
  if (cfg.noTreeshake) process.env.NO_TREESHAKE = 'true';
  if (cfg.minifyJs) process.env.MINIFY_JS = cfg.minifyJs;

  const {createServer} = await import('vite');
  const port = cfg.httpServerListenPort ?? DEFAULT_PORT;

  const headers = cfg.crossOriginIsolation
    ? {
        'Cross-Origin-Opener-Policy': 'same-origin',
        'Cross-Origin-Embedder-Policy': 'require-corp',
      }
    : undefined;

  const server = await createServer({
    configFile: pjoin(ROOT_DIR, 'ui/vite.config.mjs'),
    server: {
      host: cfg.httpServerListenHost,
      port,
      strictPort: false,
      headers,
      // Vite needs to read source files outside its root (ui/src/assets,
      // ui/src/gen via the symlink to out/, buildtools/, etc.).
      fs: {allow: [ROOT_DIR]},
    },
  });

  // Read the source index.html, patch for dev (point the inline bootstrap
  // at the frontend source entry), and serve at /.
  const indexSrc = pjoin(ROOT_DIR, 'ui/src/assets/index.html');
  const patchHtml = (raw) => {
    // Replace the prod-relative bundle path with the dev source entry.
    // Vite's transformIndexHtml will then resolve /frontend/index.ts through
    // its module graph (with HMR client injected).
    let html = raw.replace(
      /script\.src\s*=\s*version\s*\+\s*['"]\/frontend_bundle\.js['"];?/,
      `script.src = '/frontend/index.ts';`,
    );
    // Native ESM entry needs type="module". Vite also needs a global hint at
    // where versioned assets live (assetSrc()/getServingRoot() use it).
    html = html.replace(
      /script\.async\s*=\s*true;?/,
      `script.type = 'module'; window.__GLOBAL_ASSET_ROOT__ = version + '/';`,
    );
    // Patch the version map (same job as cpHtml in prod). In dev there is
    // exactly one channel served from the root, version '.'.
    const versionMap = JSON.stringify({stable: cfg.version});
    html = html.replace(
      /data-perfetto_version='[^']*'/,
      `data-perfetto_version='${versionMap}'`,
    );
    if (cfg.titleOverride) {
      html = html.replace(
        /<title>[^<]*<\/title>/,
        `<title>${cfg.titleOverride}</title>`,
      );
    }
    return html;
  };

  // Serve /test/* from the repo (used by some e2e flows). Mirrors the
  // equivalent branch in startServer().
  server.middlewares.use((req, res, next) => {
    const url = req.url.split('?', 1)[0];
    if (!url.startsWith('/test/')) return next();
    const absPath = pjoin(ROOT_DIR, url);
    if (path.relative(ROOT_DIR, absPath).startsWith('..')) {
      res.statusCode = 403;
      return res.end('403');
    }
    fs.readFile(absPath, (err, data) => {
      if (err) {
        res.statusCode = 404;
        return res.end();
      }
      res.end(data);
    });
  });

  // frontend/index.ts inserts `<link rel="stylesheet" href="frontend.css">`
  // at runtime, which is needed in prod but in dev the styles come from the
  // SCSS module that Vite transforms inline. Return a 200 empty body so the
  // link's onload fires and init can proceed.
  server.middlewares.use((req, res, next) => {
    const url = req.url.split('?', 1)[0];
    if (url === '/frontend.css' || url.endsWith('/frontend.css')) {
      res.setHeader('Content-Type', 'text/css');
      return res.end('/* dev stub: styles injected by Vite */');
    }
    next();
  });

  // Fall back to serving files from outDistRootDir / outDistDir for anything
  // Vite hasn't claimed (wasm modules, fonts under /assets/, manifest.json,
  // etc.). In prod, frontend.css lives inside the versioned dir, so the
  // url('assets/Roboto.woff2') paths in typefaces.scss resolve to
  // /<version>/assets/...; in dev the stylesheet is injected from /, so the
  // browser asks for /assets/Roboto.woff2. Try outDistDir as a second root
  // so those font requests succeed.
  server.middlewares.use((req, res, next) => {
    const url = req.url.split('?', 1)[0];
    // Vite handles JS/TS/CSS modules and HMR endpoints itself.
    if (url === '/' || url === '/index.html') return next();
    const roots = [cfg.outDistRootDir, cfg.outDistDir];
    const tryRoot = (i) => {
      if (i >= roots.length) return next();
      const root = roots[i];
      const absPath = path.normalize(pjoin(root, url));
      if (path.relative(root, absPath).startsWith('..')) return tryRoot(i + 1);
      fs.stat(absPath, (err, stat) => {
        if (err || !stat.isFile()) return tryRoot(i + 1);
        fs.readFile(absPath, (rerr, data) => {
          if (rerr) return tryRoot(i + 1);
          const ext = url.split('.').pop();
          const mime =
            {
              wasm: 'application/wasm',
              woff2: 'font/woff2',
              png: 'image/png',
              json: 'application/json',
              css: 'text/css',
              js: 'application/javascript',
              html: 'text/html',
            }[ext] || 'application/octet-stream';
          res.setHeader('Content-Type', mime);
          res.end(data);
        });
      });
    };
    tryRoot(0);
  });

  // Last: serve the patched index.html at / (and any other unmatched route,
  // mirroring the SPA convention).
  server.middlewares.use(async (req, res, next) => {
    const url = req.url.split('?', 1)[0];
    if (url !== '/' && url !== '/index.html') return next();
    try {
      const raw = fs.readFileSync(indexSrc, 'utf8');
      const patched = patchHtml(raw);
      const transformed = await server.transformIndexHtml(url, patched);
      res.setHeader('Content-Type', 'text/html');
      res.end(transformed);
    } catch (e) {
      next(e);
    }
  });

  await server.listen();
  server.printUrls();
  // Make sure the dev server is shut down on process exit.
  subprocesses.push({pid: 'vite-dev', kill: () => server.close()});
}

function startServer() {
  const server = http.createServer(function (req, res) {
    console.debug(req.method, req.url);
    let uri = req.url.split('?', 1)[0];
    if (uri.endsWith('/')) {
      uri += 'index.html';
    }

    if (uri === '/live_reload') {
      // Implements the Server-Side-Events protocol.
      const head = {
        'Content-Type': 'text/event-stream',
        'Connection': 'keep-alive',
        'Cache-Control': 'no-cache',
      };
      res.writeHead(200, head);
      const arrayIdx = httpWatches.length;
      // We never remove from the array, the delete leaves an undefined item
      // around. It makes keeping track of the index easier at the cost of a
      // small leak.
      httpWatches.push(res);
      req.on('close', () => delete httpWatches[arrayIdx]);
      return;
    }

    let absPath = path.normalize(path.join(cfg.outDistRootDir, uri));
    // We want to be able to use the data in '/test/' for e2e tests.
    // However, we don't want do create a symlink into the 'dist/' dir,
    // because 'dist/' gets shipped on the production server.
    if (uri.startsWith('/test/')) {
      absPath = pjoin(ROOT_DIR, uri);
    }

    // Don't serve contents outside of the project root (b/221101533).
    if (path.relative(ROOT_DIR, absPath).startsWith('..')) {
      res.writeHead(403);
      res.end('403 Forbidden - Request path outside of the repo root');
      return;
    }

    let stat;
    try {
      stat = fs.statSync(absPath);
    } catch (statErr) {
      res.writeHead(404);
      res.end(JSON.stringify(statErr));
      return;
    }

    // Truncate to second precision: HTTP dates have 1s resolution, so the
    // sub-millisecond part of mtime would cause a permanent mismatch.
    const mtimeSec = Math.floor(stat.mtime.getTime() / 1000) * 1000;
    const mtimeStr = new Date(mtimeSec).toUTCString();

    // Return 304 if the browser's cached copy is still fresh.
    const ifModifiedSince = req.headers['if-modified-since'];
    if (
      ifModifiedSince !== undefined &&
      new Date(ifModifiedSince).getTime() >= mtimeSec
    ) {
      res.writeHead(304);
      res.end();
      return;
    }

    fs.readFile(absPath, function (err, data) {
      if (err) {
        res.writeHead(404);
        res.end(JSON.stringify(err));
        return;
      }

      const mimeMap = {
        html: 'text/html',
        css: 'text/css',
        js: 'application/javascript',
        wasm: 'application/wasm',
      };
      const ext = uri.split('.').pop();
      const cType = mimeMap[ext] || 'octect/stream';
      const acceptsGzip = (req.headers['accept-encoding'] || '').includes(
        'gzip',
      );
      const finalize = (body) => {
        const head = {
          'Content-Type': cType,
          'Content-Length': body.length,
          'Last-Modified': mtimeStr,
          'Cache-Control': 'no-cache',
        };
        if (acceptsGzip) head['Content-Encoding'] = 'gzip';
        if (cfg.crossOriginIsolation) {
          head['Cross-Origin-Opener-Policy'] = 'same-origin';
          head['Cross-Origin-Embedder-Policy'] = 'require-corp';
        }
        res.writeHead(200, head);
        res.write(body);
        res.end();
      };
      if (acceptsGzip) {
        zlib.gzip(data, (gzErr, compressed) => {
          finalize(gzErr ? data : compressed);
        });
      } else {
        finalize(data);
      }
    });
  });

  let port = cfg.httpServerListenPort ?? DEFAULT_PORT;
  let retryCount = 0;

  // Pick the next free port starting at 10000
  server.on('error', (e) => {
    if (e.code === 'EADDRINUSE') {
      if (cfg.httpServerListenPort === undefined) {
        if (retryCount <= 10) {
          // Try the next port.
          console.log(`Port ${port} is in use, trying ${port + 1}...`);
          ++port;
          ++retryCount;
          server.listen(port, cfg.httpServerListenHost);
        } else {
          console.error(
            `ERROR: Port ${port} is in use, and no free port found after 10 tries. Exiting.`,
          );
          process.exit(1);
        }
      } else {
        console.error(
          `ERROR: Port ${port} is in use, and --serve-port was explicitly set. Exiting.`,
        );
        process.exit(1);
      }
    } else {
      console.error('HTTP SERVER ERROR:', e);
      process.exit(1);
    }
  });

  server.listen(port, cfg.httpServerListenHost);

  server.on('listening', () => {
    const {address, port} = server.address();
    const host = address == '127.0.0.1' ? 'localhost' : address;
    console.log(`HTTP server is listening on http://${host}:${port}`);
  });
}

function isDistComplete() {
  // In watch+serve mode the frontend bundle and its CSS are served live by
  // the Vite dev server, never materialised on disk. Only require the
  // artifacts that genuinely have to exist before the user can load a trace.
  const useDevServer = cfg.watch && cfg.startHttpServer;
  const requiredArtifacts = [
    ...(useDevServer ? [] : ['frontend_bundle.js', 'frontend.css']),
    'engine_bundle.js',
    'traceconv_bundle.js',
    ...cfg.wasmModules.map((wasmMod) => `${wasmMod}.wasm`),
  ];
  const relPaths = new Set();
  walk(cfg.outDistDir, (absPath) => {
    relPaths.add(path.relative(cfg.outDistDir, absPath));
  });
  for (const fName of requiredArtifacts) {
    if (!relPaths.has(fName)) return false;
  }
  return true;
}

function notifyLiveServer(changedFile) {
  // Add file to pending set
  notifyLiveServerPendingFiles.add(changedFile);

  // Clear existing timeout if any
  if (liveServerDebounceTimerId > 0) {
    clearTimeout(liveServerDebounceTimerId);
  }

  // Set new timeout to batch notifications
  liveServerDebounceTimerId = setTimeout(() => {
    // Send all pending files in one batch
    for (const cli of httpWatches) {
      if (cli === undefined) continue;
      for (const file of notifyLiveServerPendingFiles) {
        cli.write('data: ' + path.relative(cfg.outDistRootDir, file) + '\n\n');
      }
    }
    notifyLiveServerPendingFiles.clear();
    liveServerDebounceTimerId = 0;
  }, LIVE_SERVER_DEBOUNCE_MS);
}

function copyExtensionAssets() {
  addTask(cp, [
    pjoin(ROOT_DIR, 'ui/src/assets/logo-128.png'),
    pjoin(cfg.outExtDir, 'logo-128.png'),
  ]);
  addTask(cp, [
    pjoin(ROOT_DIR, 'ui/src/chrome_extension/manifest.json'),
    pjoin(cfg.outExtDir, 'manifest.json'),
  ]);
}

// -----------------------
// Task chaining functions
// -----------------------

function addTask(func, args) {
  const task = new Task(func, args);
  for (const t of tasks) {
    if (t.identity === task.identity) {
      return;
    }
  }
  tasks.push(task);
  setTimeout(runTasks, 0);
}

function runTasks() {
  const snapTasks = tasks.splice(0); // snap = std::move(tasks).
  tasksTot += snapTasks.length;
  for (const task of snapTasks) {
    const DIM = '\u001b[2m';
    const BRT = '\u001b[37m';
    const RST = '\u001b[0m';
    const ms = (performance.now() - tStart) / 1000;
    const ts = `[${DIM}${ms.toFixed(3)}${RST}]`;
    const descr = task.description.substr(0, 80);
    console.log(`${ts} ${BRT}${++tasksRan}/${tasksTot}${RST}\t${descr}`);
    task.func.apply(/* this=*/ undefined, task.args);
  }
}

// Executes all the RULES that match the given |absPath|.
function scanFile(absPath) {
  console.assert(fs.existsSync(absPath));
  console.assert(path.isAbsolute(absPath));
  const normPath = path.relative(ROOT_DIR, absPath);
  for (const rule of RULES) {
    const match = rule.r.exec(normPath);
    if (!match || match[0] !== normPath) continue;
    const captureGroup = match.length > 1 ? match[1] : undefined;
    rule.f(absPath, captureGroup);
  }
}

// Walks the passed |dir| recursively and, for each file, invokes the matching
// RULES. If --watch is used, it also installs a fswatch() and re-triggers the
// matching RULES on each file change.
function scanDir(dir, regex) {
  const filterFn = regex ? (absPath) => regex.test(absPath) : () => true;
  const absDir = path.isAbsolute(dir) ? dir : pjoin(ROOT_DIR, dir);
  // Add a fs watch if in watch mode.
  if (cfg.watch) {
    fs.watch(absDir, {recursive: true}, (_eventType, relFilePath) => {
      const filePath = pjoin(absDir, relFilePath);
      if (!filterFn(filePath)) return;
      if (cfg.verbose) {
        console.log('File change detected', _eventType, filePath);
      }
      if (fs.existsSync(filePath)) {
        scanFile(filePath, filterFn);
      }
    });
  }
  walk(absDir, (f) => {
    if (filterFn(f)) scanFile(f);
  });
}

function exec(cmd, args, opts) {
  opts = opts || {};
  opts.stdout = opts.stdout || 'inherit';
  if (cfg.verbose) console.log(`${cmd} ${args.join(' ')}\n`);
  const spwOpts = {cwd: cfg.outDir, stdio: ['ignore', opts.stdout, 'inherit']};
  if (opts.env) {
    spwOpts.env = {...process.env, ...opts.env};
  }
  const checkExitCode = (code, signal) => {
    if (signal === 'SIGINT' || signal === 'SIGTERM') return;
    if (code !== 0 && !opts.noErrCheck) {
      console.error(`${cmd} ${args.join(' ')} failed with code ${code}`);
      process.exit(1);
    }
  };
  if (opts.async) {
    const proc = childProcess.spawn(cmd, args, spwOpts);
    const procIndex = subprocesses.length;
    subprocesses.push(proc);
    return new Promise((resolve, _reject) => {
      proc.on('exit', (code, signal) => {
        delete subprocesses[procIndex];
        checkExitCode(code, signal);
        resolve();
      });
    });
  } else {
    const spawnRes = childProcess.spawnSync(cmd, args, spwOpts);
    checkExitCode(spawnRes.status, spawnRes.signal);
    return spawnRes;
  }
}

function execModule(module, args, opts) {
  const modPath = pjoin(ROOT_DIR, 'ui/node_modules/.bin', module);
  return exec(modPath, args || [], opts);
}

// ------------------------------------------
// File system & subprocess utility functions
// ------------------------------------------

class Task {
  constructor(func, args) {
    this.func = func;
    this.args = args || [];
    // |identity| is used to dedupe identical tasks in the queue.
    this.identity = JSON.stringify([this.func.name, this.args]);
  }

  get description() {
    const ret = this.func.name.startsWith('exec') ? [] : [this.func.name];
    const flattenedArgs = [].concat(...this.args);
    for (const arg of flattenedArgs) {
      if (typeof arg === 'object' && arg !== null) {
        ret.push(JSON.stringify(arg));
        continue;
      }
      const argStr = `${arg}`;
      if (argStr.startsWith('/')) {
        ret.push(path.relative(cfg.outDir, arg));
      } else {
        ret.push(argStr);
      }
    }
    return ret.join(' ');
  }
}

function walk(dir, callback, skipRegex) {
  for (const child of fs.readdirSync(dir)) {
    const childPath = pjoin(dir, child);
    const stat = fs.lstatSync(childPath);
    if (skipRegex !== undefined && skipRegex.test(child)) continue;
    if (stat.isDirectory()) {
      walk(childPath, callback, skipRegex);
    } else if (!stat.isSymbolicLink()) {
      callback(childPath);
    }
  }
}

// Recursively build a list of files in a given directory and return a list of
// file paths, similar to `find -type f`.
function listFilesRecursive(dir) {
  const fileList = [];

  walk(dir, (filePath) => {
    fileList.push(filePath);
  });

  return fileList;
}

function ensureDir(dirPath, clean) {
  const exists = fs.existsSync(dirPath);
  if (exists && clean) {
    console.log('rm', dirPath);
    fs.rmSync(dirPath, {recursive: true});
  }
  if (!exists || clean) fs.mkdirSync(dirPath, {recursive: true});
  return dirPath;
}

function cp(src, dst) {
  ensureDir(path.dirname(dst));
  if (cfg.verbose) {
    console.log(
      'cp',
      path.relative(ROOT_DIR, src),
      '->',
      path.relative(ROOT_DIR, dst),
    );
  }
  fs.copyFileSync(src, dst);
}

function mklink(src, dst) {
  // If the symlink already points to the right place don't touch it. This is
  // to avoid changing the mtime of the ui/ dir when unnecessary.
  if (fs.existsSync(dst)) {
    if (fs.lstatSync(dst).isSymbolicLink() && fs.readlinkSync(dst) === src) {
      return;
    } else {
      fs.unlinkSync(dst);
    }
  }
  fs.symlinkSync(src, dst);
}

function prepareBuildLock() {
  if (fs.existsSync(cfg.lockFile)) {
    const oldPid = fs.readFileSync(cfg.lockFile, 'utf8').trim();
    let running = true;
    try {
      // Check if oldPid exists.
      process.kill(parseInt(oldPid), 0);
    } catch (e) {
      running = false;
    }
    if (running) {
      console.error(
        `Error: a build.mjs instance is already running (${cfg.lockFile} PID=${oldPid}).`,
      );
      console.error(
        'Hint: use --no-build (-n) to skip the build and avoid the lock.',
      );
      process.exit(1);
    } else {
      console.log(`Removing stale lock file for PID ${oldPid}`);
      fs.unlinkSync(cfg.lockFile);
    }
  }
  fs.writeFileSync(cfg.lockFile, process.pid.toString());
  process.on('exit', () => releaseBuildLock());
}

function releaseBuildLock() {
  if (fs.existsSync(cfg.lockFile)) {
    const pid = fs.readFileSync(cfg.lockFile, 'utf8').trim();
    if (pid === process.pid.toString()) {
      fs.unlinkSync(cfg.lockFile);
    } else {
      console.warn(`Ignoring stale lock file PID ${pid}`);
    }
  }
}

main();
