#!/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:dev_compiler/src/compiler/js_names.dart' as js_names;
import 'package:path/path.dart' as p;

enum NullSafety { strict, weak, disabled }

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 = ArgParser(usageLineLength: 80)
    ..addOption('arch',
        abbr: 'a',
        help: "Target platform's machine architecture.",
        allowed: ['x64', 'arm64'])
    ..addOption('binary', abbr: 'b', help: 'Runtime binary path.')
    ..addOption('compile-vm-options',
        help: 'DART_VM_OPTIONS for the compilation VM.')
    ..addFlag('debug',
        abbr: 'd',
        help: 'Use current source instead of built SDK.',
        defaultsTo: false)
    ..addMultiOption('enable-experiment',
        help: 'Run with specified experiments enabled.')
    ..addFlag('help', abbr: 'h', help: 'Display this message.')
    ..addOption('mode',
        help: 'Option to (compile|run|all). Default is all (compile and run).',
        allowed: ['compile', 'run', 'all'],
        defaultsTo: 'all')
    ..addFlag('sound-null-safety',
        help: 'Compile for sound null safety at runtime. Passed through to the '
            'DDC binary. Defaults to false.',
        negatable: true,
        defaultsTo: true)
    ..addFlag('emit-debug-symbols',
        help: 'Pass through flag for DDC, emits debug symbols file along with '
            'the compiled module.',
        defaultsTo: false)
    ..addFlag('null-assertions',
        help: 'Run with assertions that values passed to non-nullable method '
            'parameters are not null.',
        defaultsTo: false)
    ..addFlag('native-null-assertions',
        help: 'Run with assertions on non-nullable values returned from native '
            'APIs.',
        negatable: true)
    ..addFlag('weak-null-safety-errors',
        help: 'Treat weak null safety warnings as errors.', defaultsTo: false)
    ..addFlag('canary',
        help: 'Enable all compiler features under active development.',
        defaultsTo: false)
    ..addFlag('observe',
        help:
            'Run the compiler in the Dart VM with --observe. Implies --debug.',
        defaultsTo: false)
    ..addOption('out', help: 'Output file.')
    ..addOption('packages', help: 'Where to find a package spec file.')
    ..addOption('port',
        abbr: 'p',
        help: 'Run with the corresponding chrome/V8 debugging port open.',
        defaultsTo: '9222')
    ..addOption('runtime',
        abbr: 'r',
        help: 'Platform to run on (node|d8|chrome).  Default is node.',
        allowed: ['node', 'd8', 'chrome'],
        defaultsTo: 'node')
    ..addFlag('summarize-text',
        help: 'Emit API summary in a .js.txt file.', defaultsTo: false)
    ..addMultiOption('summary',
        abbr: 's',
        help: 'summary file(s) of imported libraries, optionally with module '
            'import path: -s path.sum=js/import/path')
    ..addFlag('verbose',
        abbr: 'v',
        help: 'Echos the commands, arguments, and environment this script is '
            'running.',
        defaultsTo: false)
    ..addOption('vm-service-port',
        help: 'Specify the observatory port. Implied --observe.');

  var options = parser.parse(args);
  if (options['help'] as bool) {
    printUsage();
    print('Available options:');
    print(parser.usage);
    exit(0);
  }
  if (options.rest.length != 1) {
    print('Dart script file required.\n');
    printUsage();
    exit(1);
  }
  var arch = options['arch'] as String?;
  var debug = options['debug'] as bool ||
      options['observe'] as bool ||
      options.wasParsed('vm-service-port');
  var summarizeText = options['summarize-text'] as bool;
  var binary = options['binary'] as String?;
  var experiments = options['enable-experiment'] as List<String>;
  var summaries = options['summary'] as List<String>;
  var port = int.parse(options['port'] as String);
  var mode = options['mode'] as String;
  var compile = mode == 'compile' || mode == 'all';
  var run = mode == 'run' || mode == 'all';
  var verbose = options['verbose'] as bool;
  var soundNullSafety = options['sound-null-safety'] as bool;
  var emitDebugSymbols = options['emit-debug-symbols'] as bool;
  var nonNullAsserts = options['null-assertions'] as bool;
  var nativeNonNullAsserts = options.wasParsed('native-null-assertions')
      ? options['native-null-assertions'] as bool
      : soundNullSafety;
  var weakNullSafetyErrors = options['weak-null-safety-errors'] as bool;
  var canaryFeatures = options['canary'] as bool;
  var entry = p.canonicalize(options.rest.first);
  var out = (options['out'] as String?) ?? p.setExtension(entry, '.js');
  var libRoot = p.dirname(entry);
  var basename = p.basenameWithoutExtension(entry);
  var libname =
      js_names.pathToJSIdentifier(p.relative(p.withoutExtension(entry)));

  // This is used in the DDC module system and usually corresponds to the
  // entrypoint's path.
  var appname = p.relative(p.withoutExtension(entry));

  // This is used in the DDC module system for multiapp workflows and is
  // stubbed in ddb.
  var uuid = "00000000-0000-0000-0000-000000000000";

  // By default (no `-d`), we use the `dartdevc` binary on the user's path to
  // compute the SDK we use for execution.  I.e., we assume that `dart` is
  // under `$DART_SDK/bin/dart` and use that to find `dartdevc` and related
  // artifacts.  In this mode, this script can run against any installed SDK.
  // If you want to run against a freshly built SDK, that must be first on
  // your path.
  var dartBinary = Platform.resolvedExecutable;
  var dartSdk = p.dirname(p.dirname(dartBinary));

  // In debug mode (`-d`), we run from the `pkg/dev_compiler` sources.  We
  // determine the location via this actual script (i.e., `-d` assumes
  // this script remains under to `tool` sub-directory).
  var toolPath =
      Platform.script.normalizePath().toFilePath(windows: Platform.isWindows);
  var ddcPath = p.dirname(p.dirname(toolPath));
  var dartCheckoutPath = p.dirname(p.dirname(ddcPath));

  /// Runs the [command] with [args] in [environment].
  ///
  /// Will echo the commands to the console before running them when running in
  /// `verbose` mode.
  Future<Process> startProcess(String name, String command, List<String> args,
      [Map<String, String> environment = const {}]) {
    if (verbose) {
      print('Running $name:\n$command ${args.join(' ')}\n');
      if (environment.isNotEmpty) {
        var environmentVariables =
            environment.entries.map((e) => '${e.key}: ${e.value}').join('\n');
        print('With Environment:\n$environmentVariables\n');
      }
    }
    return Process.start(command, args,
        mode: ProcessStartMode.inheritStdio, environment: environment);
  }

  Future<void> runDdc(List<String> ddcArgs) async {
    var observe =
        options.wasParsed('vm-service-port') || options['observe'] as bool;
    var vmServicePort = options.wasParsed('vm-service-port')
        ? '=${options['vm-service-port']}'
        : '';
    var vmOptions = options['compile-vm-options'] as String?;
    var args = <String>[
      ...?vmOptions?.split(' '),
      if (debug) ...[
        if (observe) ...[
          '--enable-vm-service$vmServicePort',
          '--pause-isolates-on-start',
        ],
        '--enable-asserts',
        // Use unbuilt script.  This only works from a source checkout.
        p.join(ddcPath, 'bin', 'dartdevc.dart'),
      ] else
        // Use built snapshot.
        p.join(dartSdk, 'bin', 'snapshots', 'dartdevc.dart.snapshot'),
      ...ddcArgs,
    ];
    var process = await startProcess('DDC', dartBinary, args);
    if (await process.exitCode != 0) exit(await process.exitCode);
  }

  String mod;
  var chrome = false;
  var node = false;
  var d8 = false;
  var runtime = options['runtime'] as String?;
  switch (runtime) {
    case 'node':
      node = true;
      mod = 'common';
      break;
    case 'd8':
      d8 = true;
      mod = 'legacy';
      break;
    case 'chrome':
      chrome = true;
      mod = 'amd';
      break;
    default:
      throw Exception('Unexpected runtime: $runtime');
  }

  var sdkRoot = p.dirname(p.dirname(ddcPath));
  var buildDir = resolveBuildDir(sdkRoot, arch);
  var requirePath = p.join(sdkRoot, 'third_party', 'requirejs');
  var sdkOutlineDill = p.join(buildDir,
      soundNullSafety ? 'ddc_outline.dill' : 'ddc_outline_unsound.dill');
  var suffix = soundNullSafety ? p.join('sound', mod) : p.join('kernel', mod);
  var sdkJsPath = p.join(buildDir, 'gen', 'utils', 'dartdevc', suffix);

  // Print an initial empty line to separate the invocation from the output.
  if (verbose) {
    print('');
  }

  if (compile) {
    var ddcArgs = [
      if (summarizeText) '--summarize-text',
      '--modules=$mod',
      '--dart-sdk-summary=$sdkOutlineDill',
      for (var summary in summaries) '--summary=$summary',
      for (var experiment in experiments) '--enable-experiment=$experiment',
      if (soundNullSafety) '--sound-null-safety' else '--no-sound-null-safety',
      if (options['packages'] != null) '--packages=${options['packages']}',
      if (emitDebugSymbols) '--emit-debug-symbols',
      if (canaryFeatures) '--canary',
      '-o',
      out,
      entry
    ];
    await runDdc(ddcArgs);
  }

  if (run) {
    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({
    paths: {
        'dart_sdk': '$sdkJsPath/dart_sdk',
    },
    waitSeconds: 15
  });
  require(['dart_sdk', '$basename'],
        function(sdk, app) {
    'use strict';

    sdk.dart.weakNullSafetyWarnings(
        !($weakNullSafetyErrors || $soundNullSafety));
    sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
    sdk.dart.nonNullAsserts($nonNullAsserts);
    sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
    sdk._debugger.registerDevtoolsFormatter();
    app.$libname.main([]);
  });
</script>
''';
      var htmlFile = p.setExtension(out, '.html');
      File(htmlFile).writeAsStringSync(html);
      var tmp = p.join(Directory.systemTemp.path, 'ddc');

      var process = await startProcess('Chrome', chromeBinary, [
        '--auto-open-devtools-for-tabs',
        '--allow-file-access-from-files',
        '--remote-debugging-port=$port',
        '--user-data-dir=$tmp',
        htmlFile
      ]);
      if (await process.exitCode != 0) exit(await process.exitCode);
    } 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\");
// Create a self reference for JS interop tests that set fields on self.
sdk.dart.global.self = sdk.dart.global;
let main = require(\"./$basename\").$libname.main;
try {
  sdk.dart.weakNullSafetyWarnings(
      !($weakNullSafetyErrors || $soundNullSafety));
  sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
  sdk.dart.nonNullAsserts($nonNullAsserts);
  sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);
  sdk._isolate_helper.startRootIsolate(main, []);
} catch(e) {
  if (!source_maps) {
    console.log('For Dart source maps: npm install source-map-support');
  }
  sdk.core.print(sdk.dart.stackTrace(e));
  process.exit(1);
}
''';
      var nodeFile = p.setExtension(out, '.run.js');
      File(nodeFile).writeAsStringSync(runjs);
      var nodeBinary = binary ?? 'node';
      var process = await startProcess('Node', nodeBinary,
          ['--inspect=localhost:$port', nodeFile], {'NODE_PATH': nodePath});
      if (await process.exitCode != 0) exit(await process.exitCode);
    } else if (d8) {
      var runjs = '''
load("$ddcPath/lib/js/legacy/dart_library.js");
load("$sdkJsPath/dart_sdk.js");
load("$out");

let sdk = dart_library.import('dart_sdk');
// Create a self reference for JS interop tests that set fields on self.
sdk.dart.global.self = sdk.dart.global;
sdk.dart.weakNullSafetyWarnings(
    !($weakNullSafetyErrors || $soundNullSafety));
sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
sdk.dart.nonNullAsserts($nonNullAsserts);
sdk.dart.nativeNonNullAsserts($nativeNonNullAsserts);

// Invoke main through the d8 preamble to ensure the code is running
// within the fake event loop.
self.dartMainRunner(function () {
  dart_library.start("$appname", "$uuid", "$basename", "$libname", false);
});
''';
      var dart2jsD8Preamble =
          '$sdkRoot/sdk/lib/_internal/js_runtime/lib/preambles/d8.js';
      var d8File = p.setExtension(out, '.d8.js');
      File(d8File).writeAsStringSync(runjs);
      var d8Binary = binary ?? p.join(dartCheckoutPath, _d8executable);
      var process =
          await startProcess('D8', d8Binary, [dart2jsD8Preamble, d8File]);
      if (await process.exitCode != 0) exit(await process.exitCode);
    }
  }
}

String get _d8executable {
  if (Platform.isWindows) {
    return p.join('third_party', 'd8', 'windows', 'd8.exe');
  } else if (Platform.isLinux) {
    return p.join('third_party', 'd8', 'linux', 'd8');
  } else if (Platform.isMacOS) {
    return p.join('third_party', 'd8', 'macos', 'd8');
  }
  throw UnsupportedError('Unsupported platform.');
}

/// Maps supported unames to supported architectures.
final _resolvedUnames = {
  'arm64': 'arm64',
  'x86_64': 'x64',
  'x64': 'x64',
};

/// Returns the location of the Dart SDK's build directory.
String resolveBuildDir(String sdkRoot, String? architecture) {
  String platformString;
  String archString;
  if (Platform.isMacOS) {
    platformString = 'xcodebuild';
    var resolvedArchitecture = architecture;
    if (architecture == null) {
      var result = Process.runSync('uname', ['-m']).stdout as String;
      final uname = result.trim();
      resolvedArchitecture = _resolvedUnames[uname] ?? uname;
    }
    if (resolvedArchitecture == 'x64') {
      archString = 'ReleaseX64';
    } else if (resolvedArchitecture == 'arm64') {
      archString = 'ReleaseARM64';
    } else {
      throw UnsupportedError(
          'DDB does not currently support the architecture $architecture '
          'on MacOS.');
    }
  } else if (Platform.isLinux || Platform.isWindows) {
    platformString = 'out';
    if (architecture != null && architecture != 'x64') {
      throw UnsupportedError(
          'DDB does not currently support the architecture $architecture '
          'on Windows or Linux.');
    }
    archString = 'ReleaseX64';
  } else {
    throw UnsupportedError('Unsupported platform.');
  }
  return p.join(sdkRoot, platformString, archString);
}
