// 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.

'use strict';


// 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 ||
// +----------------------+   | +----------+             +--------------------+|
//                            +------------------------------------------------+

const argparse = require('argparse');
const childProcess = require('child_process');
const crypto = require('crypto');
const fs = require('fs');
const http = require('http');
const path = require('path');
const zlib = require('zlib');
const pjoin = path.join;

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

const cfg = {
  minifyJs: '',
  noSourceMaps: false,
  noTreeshake: false,
  watch: false,
  verbose: false,
  debug: false,
  bigtrace: 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},
  {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\/assets\/.+[.]scss|ui\/src\/(?:plugins|core_plugins)\/.+[.]scss/, f: compileScss},
  {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('--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.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();
    generateImports('ui/src/core_plugins', 'all_core_plugins');
    generateImports('ui/src/plugins', 'all_plugins');
    scanDir('ui/src/assets');
    scanDir('ui/src/plugins', /[.]scss$/);
    scanDir('ui/src/core_plugins', /[.]scss$/);
    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.check) {
      for (const prj of tsProjects) {
        transpileTsProject(prj, {noEmit: true});
      }
    } else {
      for (const prj of tsProjects) {
        // When in watch mode, don't error out if we get typescript errors in the
        // initial build. Typescript errors on subsequent incremental builds don't
        // error out so the initial build should behave in the same way.
        //
        // Note: In non-watch mode, we do still break on typescript errors,
        // there's no change here.
        transpileTsProject(prj, {noErrCheck: cfg.watch});
      }

      if (cfg.watch) {
        for (const prj of tsProjects) {
          transpileTsProject(prj, {watch: cfg.watch});
        }
      }

      bundleJs('rollup.config.js');
      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) {
    startServer();
  }
  if (args.run_unittests) {
    runTests('jest.unittest.config.js');
  }
}

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

function runTests(cfgFile) {
  const args = [
    '--rootDir',
    cfg.outTscDir,
    '--verbose',
    '--runInBand',
    '--detectOpenHandles',
    '--forceExit',
    '--projects',
    pjoin(ROOT_DIR, 'ui/config', cfgFile),
  ];
  if (cfg.testFilter.length > 0) {
    args.push('-t', cfg.testFilter);
  }
  if (cfg.watch) {
    args.push('--watchAll');
    addTask(execModule, ['jest', args, {async: true}]);
  } else {
    addTask(execModule, ['jest', 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 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 compileScss() {
  const src = pjoin(ROOT_DIR, 'ui/src/assets/perfetto.scss');
  const dst = pjoin(cfg.outDistDir, 'perfetto.css');
  // In watch mode, don't exit(1) if scss fails. It can easily happen by
  // having a typo in the css. It will still print an error.
  const noErrCheck = !!cfg.watch;
  const args = [src, dst];
  if (!cfg.verbose) {
    args.unshift('--quiet');
  }
  addTask(execModule, ['sass', args, {noErrCheck}]);
  if (cfg.bigtrace) {
    const srcBt = pjoin(ROOT_DIR, 'ui/src/assets/bigtrace.scss');
    const dstBt = pjoin(cfg.outBigtraceDistDir, 'bigtrace.css');
    const argsBt = [srcBt, dstBt];
    if (!cfg.verbose) {
      argsBt.unshift('--quiet');
    }
    addTask(execModule, ['sass', argsBt, {noErrCheck}]);
  }
}

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

function generateImports(dir, name) {
  // We have to use the symlink (ui/src/gen) rather than cfg.outGenDir
  // below since we want to generate the correct relative imports. For example:
  // ui/src/frontend/foo.ts
  //    import '../gen/all_plugins.ts';
  // ui/src/gen/all_plugins.ts (aka ui/out/tsc/gen/all_plugins.ts)
  //    import '../frontend/some_plugin.ts';
  const dstTs = pjoin(ROOT_DIR, 'ui/src/gen', name);
  const inputDir = pjoin(ROOT_DIR, dir);
  const args = [GEN_IMPORTS_SCRIPT, inputDir, '--out', dstTs];
  addTask(exec, ['python3', args]);
}

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

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

// Creates the three {frontend, controller, engine}_bundle.js in one invocation.
function bundleJs(cfgName) {
  const rcfg = pjoin(ROOT_DIR, 'ui/config', cfgName);
  const args = ['-c', rcfg, '--no-indent'];
  if (cfg.bigtrace) {
    args.push('--environment', 'ENABLE_BIGTRACE:true');
  }
  if (cfg.openPerfettoTrace) {
    args.push('--environment', 'ENABLE_OPEN_PERFETTO_TRACE:true');
  }
  if (cfg.minifyJs) {
    args.push('--environment', `MINIFY_JS:${cfg.minifyJs}`);
  }
  if (cfg.noSourceMaps) {
    args.push('--environment', 'NO_SOURCE_MAPS:true');
  }
  if (cfg.noTreeshake) {
    args.push('--environment', 'NO_TREESHAKE:true');
  }
  if (cfg.onlyWasmMemory64) {
    args.push('--environment', `IS_MEMORY64_ONLY:${cfg.onlyWasmMemory64}`);
  }
  args.push(...(cfg.verbose ? [] : ['--silent']));
  if (cfg.watch) {
    // --waitForBundleInput is sadly quite busted so it is required ts
    // has build at least once before invoking this.
    args.push('--watch', '--no-watch.clearScreen');
    addTask(execModule, ['rollup', args, {async: true}]);
  } else {
    addTask(execModule, ['rollup', args]);
  }
}

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

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() {
  const requiredArtifacts = [
    'frontend_bundle.js',
    'engine_bundle.js',
    'traceconv_bundle.js',
    'perfetto.css',
    ...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']};
  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.js 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();
