// Copyright (c) 2020, 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.

import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';

import 'package:args/args.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart'
    show Verbosity;
import 'package:path/path.dart';
import 'package:pub/pub.dart';

import '../core.dart';
import '../experiments.dart';
import '../sdk.dart';
import '../utils.dart';
import '../vm_interop_handler.dart';

class RunCommand extends DartdevCommand {
  static const String cmdName = 'run';

  // kErrorExitCode, as defined in runtime/bin/error_exit.h
  static const errorExitCode = 255;

  // This argument parser is here solely to ensure that VM specific flags are
  // provided before any command and to provide a more consistent help message
  // with the rest of the tool.
  @override
  ArgParser createArgParser() {
    return ArgParser(
      // Don't parse flags after script name.
      allowTrailingOptions: false,
      usageLineLength: dartdevUsageLineLength,
    );
  }

  RunCommand({bool verbose = false})
      : super(
          cmdName,
          'Run a Dart program.',
        ) {
    // NOTE: When updating this list of flags, be sure to add any VM flags to
    // the list of flags in Options::ProcessVMDebuggingOptions in
    // runtime/bin/main_options.cc. Failure to do so will result in those VM
    // options being ignored.
    argParser
      ..addSeparator(
        'Debugging options:',
      )
      ..addOption(
        'observe',
        help: 'The observe flag is a convenience flag used to run a program '
            'with a set of common options useful for debugging.',
        valueHelp: '[<port>[/<bind-address>]]',
      )
      ..addOption('launch-dds', hide: true, help: 'Launch DDS.')
      ..addSeparator(
        'Options implied by --observe are currently:',
      )
      ..addOption(
        'enable-vm-service',
        help: 'Enables the VM service and listens on the specified port for '
            'connections (default port number is 8181, default bind address '
            'is localhost).',
        valueHelp: '[<port>[/<bind-address>]]',
      )
      ..addFlag(
        'pause-isolates-on-exit',
        help: 'Pause isolates on exit when '
            'running with --enable-vm-service.',
      )
      ..addFlag(
        'pause-isolates-on-unhandled-exceptions',
        help: 'Pause isolates when an unhandled exception is encountered '
            'when running with --enable-vm-service.',
      )
      ..addFlag(
        'warn-on-pause-with-no-debugger',
        help: 'Print a warning when an isolate pauses with no attached debugger'
            ' when running with --enable-vm-service.',
      )
      ..addSeparator(
        'Other debugging options:',
      )
      ..addFlag(
        'pause-isolates-on-start',
        help: 'Pause isolates on start when '
            'running with --enable-vm-service.',
      )
      ..addFlag(
        'enable-asserts',
        help: 'Enable assert statements.',
      )
      ..addOption(
        'verbosity',
        help: 'Sets the verbosity level of the compilation.',
        defaultsTo: Verbosity.defaultValue,
        allowed: Verbosity.allowedValues,
        allowedHelp: Verbosity.allowedValuesHelp,
      );

    if (verbose) {
      argParser
        ..addSeparator(
          'Advanced options:',
        );
    }
    argParser
      ..addMultiOption(
        'define',
        abbr: 'D',
        valueHelp: 'key=value',
        help: 'Define an environment declaration.',
      )
      ..addFlag(
        'disable-service-auth-codes',
        hide: !verbose,
        negatable: false,
        help: 'Disables the requirement for an authentication code to '
            'communicate with the VM service. Authentication codes help '
            'protect against CSRF attacks, so it is not recommended to '
            'disable them unless behind a firewall on a secure device.',
      )
      ..addFlag(
        'enable-service-port-fallback',
        hide: !verbose,
        negatable: false,
        help: 'When the VM service is told to bind to a particular port, '
            'fallback to 0 if it fails to bind instread of failing to '
            'start.',
      )
      ..addOption(
        'namespace',
        hide: !verbose,
        valueHelp: 'path',
        help: 'The path to a directory that dart:io calls will treat as the '
            'root of the filesystem.',
      )
      ..addOption(
        'root-certs-file',
        hide: !verbose,
        valueHelp: 'path',
        help: 'The path to a file containing the trusted root certificates '
            'to use for secure socket connections.',
      )
      ..addOption(
        'root-certs-cache',
        hide: !verbose,
        valueHelp: 'path',
        help: 'The path to a cache directory containing the trusted root '
            'certificates to use for secure socket connections.',
      )
      ..addFlag(
        'trace-loading',
        hide: !verbose,
        negatable: false,
        help: 'Enables tracing of library and script loading.',
      );
    addExperimentalFlags(argParser, verbose);
  }

  @override
  String get invocation => '${super.invocation} <dart file | package target>';

  @override
  FutureOr<int> run() async {
    var mainCommand = '';
    var runArgs = <String>[];
    if (argResults.rest.isNotEmpty) {
      mainCommand = argResults.rest.first;
      // The command line arguments after the command name.
      runArgs = argResults.rest.skip(1).toList();
    }
    // --launch-dds is provided by the VM if the VM service is to be enabled. In
    // that case, we need to launch DDS as well.
    String launchDdsArg = argResults['launch-dds'];
    String ddsHost = '';
    String ddsPort = '';
    bool launchDds = false;
    if (launchDdsArg != null) {
      launchDds = true;
      final ddsUrl = launchDdsArg.split(':');
      ddsHost = ddsUrl[0];
      ddsPort = ddsUrl[1];
    }

    bool disableServiceAuthCodes = argResults['disable-service-auth-codes'];

    // If the user wants to start a debugging session we need to do some extra
    // work and spawn a Dart Development Service (DDS) instance. DDS is a VM
    // service intermediary which implements the VM service protocol and
    // provides non-VM specific extensions (e.g., log caching, client
    // synchronization).
    _DebuggingSession debugSession;
    if (launchDds) {
      debugSession = _DebuggingSession();
      if (!await debugSession.start(
          ddsHost, ddsPort, disableServiceAuthCodes)) {
        return errorExitCode;
      }
    }

    String path;
    String packagesConfigOverride;

    try {
      final filename = maybeUriToFilename(mainCommand);
      if (File(filename).existsSync()) {
        // TODO(sigurdm): getExecutableForCommand is able to figure this out,
        // but does not return a package config override.
        path = filename;
        packagesConfigOverride = null;
      } else {
        path = await getExecutableForCommand(mainCommand);
        packagesConfigOverride =
            join(current, '.dart_tool', 'package_config.json');
      }
    } on CommandResolutionFailedException catch (e) {
      log.stderr(e.message);
      return errorExitCode;
    }
    VmInteropHandler.run(
      path,
      runArgs,
      packageConfigOverride: packagesConfigOverride,
    );
    return 0;
  }
}

/// Try parsing [maybeUri] as a file uri or [maybeUri] itself if that fails.
String maybeUriToFilename(String maybeUri) {
  try {
    return Uri.parse(maybeUri).toFilePath();
  } catch (_) {
    return maybeUri;
  }
}

class _DebuggingSession {
  Future<bool> start(
      String host, String port, bool disableServiceAuthCodes) async {
    final ddsSnapshot = (dirname(sdk.dart).endsWith('bin'))
        ? sdk.ddsSnapshot
        : absolute(dirname(sdk.dart), 'gen', 'dds.dart.snapshot');
    if (!Sdk.checkArtifactExists(ddsSnapshot)) {
      return false;
    }
    ServiceProtocolInfo serviceInfo = await Service.getInfo();
    // Wait for VM service to publish its connection info.
    while (serviceInfo.serverUri == null) {
      await Future.delayed(Duration(milliseconds: 10));
      serviceInfo = await Service.getInfo();
    }
    final process = await Process.start(
        sdk.dart,
        [
          if (dirname(sdk.dart).endsWith('bin'))
            sdk.ddsSnapshot
          else
            absolute(dirname(sdk.dart), 'gen', 'dds.dart.snapshot'),
          serviceInfo.serverUri.toString(),
          host,
          port,
          disableServiceAuthCodes.toString(),
        ],
        mode: ProcessStartMode.detachedWithStdio);
    final completer = Completer<void>();
    StreamSubscription sub;
    sub = process.stderr.transform(utf8.decoder).listen((event) {
      if (event == 'DDS started') {
        sub.cancel();
        completer.complete();
      } else if (event.contains('Failed to start DDS')) {
        sub.cancel();
        completer.completeError(event.replaceAll(
          'Failed to start DDS',
          'Could not start Observatory HTTP server',
        ));
      }
    });
    try {
      await completer.future;
      return true;
    } catch (e) {
      stderr.write(e);
      return false;
    }
  }
}
