#!/usr/bin/env dart
// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

//
// Compiles code with DDC and runs the resulting code with either node or
// chrome.
//
// The first script supplied should be the one with `main()`.
//
// Saves the output in the same directory as the sources for convenient
// inspection, modification or rerunning the code.

import 'dart:io';

import 'package:args/args.dart' show ArgParser;
import 'package:path/path.dart' as path;

// TODO(vsm): Remove this once we stop ignoring.  It's off here, but
// configurable for manual testing.
const ignoreWhitelistedErrors = false;

void main(List<String> args) async {
  void printUsage() {
    print('Usage: ddb [options] <dart-script-file>\n');
    print('Compiles <dart-script-file> with the dev_compiler and runs it on a '
        'JS platform.\n');
  }

  // Parse flags.
  var parser = new ArgParser()
    ..addFlag('help', abbr: 'h', help: 'Display this message.')
    ..addFlag('kernel',
        abbr: 'k', help: 'Compile with the new kernel-based front end.')
    ..addFlag('debug',
        abbr: 'd',
        help: 'Use current source instead of built SDK.',
        defaultsTo: false)
    ..addOption('runtime',
        abbr: 'r',
        help: 'Platform to run on (node|d8|chrome).  Default is node.',
        allowed: ['node', 'd8', 'chrome'],
        defaultsTo: 'node')
    ..addOption('port',
        abbr: 'p',
        help: 'Run with the corresponding chrome/V8 debugging port open.',
        defaultsTo: '9222')
    ..addOption('enable-experiment',
        help: 'Run with specified experiments enabled.', defaultsTo: '')
    ..addOption('binary', abbr: 'b', help: 'Runtime binary path.');

  var options = parser.parse(args);
  if (options['help']) {
    printUsage();
    print('Available options:');
    print(parser.usage);
    exit(0);
  }
  if (options.rest.length != 1) {
    print('Dart script file required.\n');
    printUsage();
    exit(1);
  }
  var entry = options.rest.first;
  var libRoot = path.dirname(entry);
  var basename = path.basenameWithoutExtension(entry);

  var debug = options['debug'] as bool;
  var kernel = options['kernel'] as bool;
  var binary = options['binary'] as String;
  var experiment = options['enable-experiment'] as String;
  var port = int.parse(options['port'] as String);

  var dartBinary = Platform.resolvedExecutable;
  var dartPath = path.dirname(dartBinary);
  var dartSdk = path.dirname(dartPath);
  var toolPath = Platform.script.normalizePath().toFilePath();
  var ddcPath = path.dirname(path.dirname(toolPath));

  ProcessResult runDdc(String command, List<String> args) {
    if (debug) {
      // Use unbuilt script.  This only works from a source checkout.
      args.insertAll(0,
          ['--enable-asserts', path.join(ddcPath, 'bin', '${command}.dart')]);
      command = dartBinary;
    } else {
      // Use built snapshot.
      command = path.join(dartPath, command);
    }
    return Process.runSync(command, args);
  }

  /// Writes stdout and stderr from [result] to this process.
  ///
  /// Will exit with the exit code from [result] when it's not zero.
  void echoResult(ProcessResult result) async {
    stdout.write(result.stdout);
    await stdout.flush();
    stderr.write(result.stderr);
    await stderr.flush();
    if (result.exitCode != 0) exit(result.exitCode);
  }

  String mod;
  bool chrome = false;
  bool node = false;
  bool d8 = false;
  switch (options['runtime']) {
    case 'node':
      node = true;
      mod = 'common';
      break;
    case 'd8':
      d8 = true;
      mod = 'es6';
      break;
    case 'chrome':
      chrome = true;
      mod = 'amd';
      break;
  }

  String sdkJsPath;
  String requirePath;
  String ddcSdk;
  if (debug) {
    var sdkRoot = path.dirname(path.dirname(ddcPath));
    var buildDir = path.join(sdkRoot, Platform.isMacOS ? 'xcodebuild' : 'out');
    sdkJsPath = path.join(buildDir, 'ReleaseX64', 'gen', 'utils', 'dartdevc',
        kernel ? 'kernel' : 'js', mod);
    requirePath = path.join(sdkRoot, 'third_party', 'requirejs');
    ddcSdk = path.join(buildDir, 'ReleaseX64', 'gen', 'utils', 'dartdevc',
        kernel ? path.join('kernel', 'ddc_sdk.dill') : 'ddc_sdk.sum');
  } else {
    var suffix = kernel ? path.join('kernel', mod) : mod;
    sdkJsPath = path.join(dartSdk, 'lib', 'dev_compiler', suffix);
    requirePath = sdkJsPath;
    ddcSdk = path.join(
        dartSdk, 'lib', '_internal', kernel ? 'ddc_sdk.dill' : 'ddc_sdk.sum');
  }
  ProcessResult result;
  var ddcArgs = [
    if (kernel) '--kernel',
    '--modules=$mod',
    '--dart-sdk-summary=$ddcSdk',
    // TODO(nshahan) Cleanup when we settle on using or removing library-root.
    if (!kernel)
      '--library-root=$libRoot',
    if (experiment.isNotEmpty)
      '--enable-experiment=$experiment',
    '-o',
    '$libRoot/$basename.js',
    entry
  ];

  result = runDdc('dartdevc', ddcArgs);
  await echoResult(result);

  if (chrome) {
    String chromeBinary;
    if (binary != null) {
      chromeBinary = binary;
    } else if (Platform.isWindows) {
      chromeBinary =
          'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe';
    } else if (Platform.isMacOS) {
      chromeBinary =
          '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
    } else {
      // Assume Linux
      chromeBinary = 'google-chrome';
    }

    var html = """
<script src='$requirePath/require.js'></script>
<script>
  require.config({
    baseUrl: '$libRoot',
    paths: {
        'dart_sdk': '$sdkJsPath/dart_sdk'
    },
    waitSeconds: 15
  });
  require(['dart_sdk', '$basename'],
        function(sdk, app) {
    'use strict';
    sdk._debugger.registerDevtoolsFormatter();
    sdk.dart.ignoreWhitelistedErrors($ignoreWhitelistedErrors);
    app.$basename.main();
  });
</script>
""";
    var htmlFile = '$libRoot/$basename.html';
    new File(htmlFile).writeAsStringSync(html);
    var tmp = path.join(Directory.systemTemp.path, 'ddc');

    result = Process.runSync(chromeBinary, [
      '--auto-open-devtools-for-tabs',
      '--allow-file-access-from-files',
      '--remote-debugging-port=$port',
      '--user-data-dir=$tmp',
      htmlFile
    ]);
  } else if (node) {
    var nodePath = '$sdkJsPath:$libRoot';
    var runjs = '''
    let source_maps;
    try {
      source_maps = require('source-map-support');
      source_maps.install();
    } catch(e) {
    }
    let sdk = require(\"dart_sdk\");
    let main = require(\"./$basename\").$basename.main;
    sdk.dart.ignoreWhitelistedErrors($ignoreWhitelistedErrors);
    try {
      sdk._isolate_helper.startRootIsolate(main, []);
    } catch(e) {
      if (!source_maps) {
        console.log('For Dart source maps: npm install source-map-support');
      }
      console.error(e);
      process.exit(1);
    }
    ''';
    var nodeFile = '$libRoot/$basename.run.js';
    new File(nodeFile).writeAsStringSync(runjs);
    var nodeBinary = binary ?? 'node';
    result = Process.runSync(
        nodeBinary, ['--inspect=localhost:$port', nodeFile],
        environment: {'NODE_PATH': nodePath});
  } else if (d8) {
    var runjs = '''
    import { dart, _isolate_helper } from '$sdkJsPath/dart_sdk.js';
    import { $basename } from '$basename.js';
    let main = $basename.main;
    dart.ignoreWhitelistedErrors($ignoreWhitelistedErrors);
    try {
      _isolate_helper.startRootIsolate(() => {}, []);
      main();
    } catch(e) {
      console.error(e);
    }
    ''';
    var d8File = '$libRoot/$basename.d8.js';
    new File(d8File).writeAsStringSync(runjs);
    var d8Binary = binary ?? 'd8';
    result = Process.runSync(d8Binary, ['--module', d8File]);
  }
  await echoResult(result);
}
