// 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 builds the perfetto.dev docs website.

const argparse = require('argparse');
const child_process = require('child_process');
const fs = require('fs');
const http = require('http');
const path = require('path');
const fswatch = require('node-watch');  // Like fs.watch(), but works on Linux.
const pjoin = path.join;

const ROOT_DIR = path.dirname(path.dirname(__dirname));  // The repo root.

const cfg = {
  watch: false,
  verbose: false,
  startHttpServer: false,

  outDir: pjoin(ROOT_DIR, 'out/perfetto.dev'),
};

function main() {
  const parser = new argparse.ArgumentParser();
  parser.add_argument('--out', {help: 'Output directory'});
  parser.add_argument('--watch', '-w', {action: 'store_true'});
  parser.add_argument('--serve', '-s', {action: 'store_true'});
  parser.add_argument('--verbose', '-v', {action: 'store_true'});

  const args = parser.parse_args();
  cfg.outDir = path.resolve(ensureDir(args.out || cfg.outDir, /*clean=*/ true));
  cfg.watch = !!args.watch;
  cfg.verbose = !!args.verbose;
  cfg.startHttpServer = args.serve;

  // Check that deps are current before starting.
  const installBuildDeps = pjoin(ROOT_DIR, 'tools/install-build-deps');

  // --filter=nodejs --filter=gn --filter=ninja is to match what
  // cloud_build_entrypoint.sh passes to install-build-deps. It doesn't bother
  // installing the full toolchains because, unlike the Perfetto UI, it doesn't
  // need Wasm.
  const depsArgs = ['--check-only=/dev/null', '--ui', '--filter=nodejs',
                    '--filter=gn', '--filter=ninja'];
  exec(installBuildDeps, depsArgs);

  ninjaBuild();

  if (args.watch) {
    watchDir('docs');
    watchDir('infra/perfetto.dev/src/assets');
    watchDir('protos');
    watchDir('python');
    watchDir('src/trace_processor/tables');
  }
  if (args.serve) {
    startServer();
  }
}

function ninjaBuild() {
  exec(
      pjoin(ROOT_DIR, 'tools/gn'),
      ['gen', cfg.outDir, '--args=enable_perfetto_site=true']);
  exec(pjoin(ROOT_DIR, 'tools/ninja'), ['-C', cfg.outDir, 'site']);
}

function startServer() {
  const port = 8082;
  console.log(`Starting HTTP server on http://localhost:${port}`)
  const serveDir = path.join(cfg.outDir, 'site');
  http.createServer(function(req, res) {
        console.debug(req.method, req.url);
        let uri = req.url.split('?', 1)[0];
        uri += uri.endsWith('/') ? 'index.html' : '';

        // Disallow serving anything outside out directory.
        const absPath = path.normalize(path.join(serveDir, uri));
        const relative = path.relative(serveDir, absPath);
        if (relative.startsWith('..')) {
          res.writeHead(404);
          res.end();
          return;
        }

        fs.readFile(absPath, function(err, data) {
          if (err) {
            res.writeHead(404);
            res.end(JSON.stringify(err));
            return;
          }
          const mimeMap = {
            'css': 'text/css',
            'png': 'image/png',
            'svg': 'image/svg+xml',
            'js': 'application/javascript',
          };
          const contentType = mimeMap[uri.split('.').pop()] || 'text/html';
          const head = {
            'Content-Type': contentType,
            'Content-Length': data.length,
            'Cache-Control': 'no-cache',
          };
          res.writeHead(200, head);
          res.end(data);
        });
      })
      .listen(port, 'localhost');
}

function watchDir(dir) {
  const absDir = path.isAbsolute(dir) ? dir : pjoin(ROOT_DIR, dir);
  // Add a fs watch if in watch mode.
  if (cfg.watch) {
    fswatch(absDir, {recursive: true}, (_eventType, filePath) => {
      if (cfg.verbose) {
        console.log('File change detected', _eventType, filePath);
      }
      ninjaBuild();
    });
  }
}

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);
    }
  };
  const spawnRes = child_process.spawnSync(cmd, args, spwOpts);
  checkExitCode(spawnRes.status, spawnRes.signal);
  return spawnRes;
}

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

main();
