#!/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('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('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 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 nonNullAsserts = options['null-assertions'] as bool;
  var nativeNonNullAsserts = options['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 =
      p.join(sdkRoot, Platform.isMacOS ? 'xcodebuild' : 'out', 'ReleaseX64');
  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']}',
      '-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) {
      // Fix SDK import.  `d8` doesn't let us set paths, so we need a full path
      // to the SDK.

      var jsFile = File(out);
      var jsContents = jsFile.readAsStringSync();
      jsContents = jsContents.replaceFirst(
          "from 'dart_sdk.js'", "from '$sdkJsPath/dart_sdk.js'");
      jsFile.writeAsStringSync(jsContents);

      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);
dart_library.start('$basename', '$libname');
''';
      var d8File = p.setExtension(out, '.d8.js');
      File(d8File).writeAsStringSync(runjs);
      var d8Binary = binary ?? p.join(dartCheckoutPath, _d8executable);
      var process = await startProcess('D8', d8Binary, ['--module', 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.');
}
