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

// @dart = 2.9

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

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.',
        defaultsTo: false)
    ..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.',
        defaultsTo: true,
        negatable: true)
    ..addFlag('weak-null-safety-errors',
        help: 'Treat weak null safety warnings as errors.', 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;
  var summaries = options['summary'] as List;
  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['native-null-assertions'] as bool;
  var weakNullSafetyErrors = options['weak-null-safety-errors'] 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 =
      module_builder.pathToJSIdentifier(p.relative(p.withoutExtension(entry)));

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

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

  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_sound.dill' : 'ddc_outline.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',
      if (options['packages'] != null) '--packages=${options['packages']}',
      if (emitDebugSymbols) '--emit-debug-symbols',
      '-o',
      out,
      entry
    ];
    await runDdc('dartdevc', 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("$basename", "$libname");
});
''';
      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';
    String resolvedArchitecture = architecture;
    if (architecture == null) {
      final uname = Process.runSync('uname', ['-m']).stdout.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);
}
