// 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:io' as io;
import 'dart:isolate';

import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:cli_util/cli_logging.dart';
import 'package:dart_style/src/cli/format_command.dart';
import 'package:nnbd_migration/migration_cli.dart';
import 'package:usage/usage.dart';

import 'src/analytics.dart';
import 'src/commands/analyze.dart';
import 'src/commands/compile.dart';
import 'src/commands/create.dart';
import 'src/commands/fix.dart';
import 'src/commands/pub.dart';
import 'src/commands/run.dart';
import 'src/commands/test.dart';
import 'src/core.dart';
import 'src/experiments.dart';
import 'src/utils.dart';
import 'src/vm_interop_handler.dart';

/// This is typically called from bin/, but given the length of the method and
/// analytics logic, it has been moved here. Also note that this method calls
/// [io.exit(code)] directly.
Future<void> runDartdev(List<String> args, SendPort port) async {
  VmInteropHandler.initialize(port);
  final stopwatch = Stopwatch();
  int result;

  // The Analytics instance used to report information back to Google Analytics,
  // see lib/src/analytics.dart.
  Analytics analytics;

  // The exit code for the dartdev process, null indicates that it has not yet
  // been set yet. The value is set in the catch and finally blocks below.
  int exitCode;

  // Any caught non-UsageExceptions when running the sub command
  Object exception;
  StackTrace stackTrace;

  analytics =
      createAnalyticsInstance(args.contains('--disable-dartdev-analytics'));

  // If we have not printed the analyticsNoticeOnFirstRunMessage to stdout,
  // the user is on a terminal, and the machine is not a bot, then print the
  // disclosure and set analytics.disclosureShownOnTerminal to true.
  if (analytics is DartdevAnalytics &&
      !analytics.disclosureShownOnTerminal &&
      io.stdout.hasTerminal &&
      !isBot()) {
    print(analyticsNoticeOnFirstRunMessage);
    analytics.disclosureShownOnTerminal = true;
  }

  // When `--disable-analytics` or `--enable-analytics` are called we perform
  // the respective intention and print any notices to standard out and exit.
  if (args.contains('--disable-analytics')) {
    // This block also potentially catches the case of (disableAnalytics &&
    // enableAnalytics), in which we favor the disabling of analytics.
    analytics.enabled = false;

    // Alert the user that analytics have been disabled:
    print(analyticsDisabledNoticeMessage);
    io.exit(0);
  } else if (args.contains('--enable-analytics')) {
    analytics.enabled = true;

    // Alert the user again that anonymous data will be collected:
    print(analyticsNoticeOnFirstRunMessage);
    io.exit(0);
  }

  // --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.
  // TODO(bkonyi): add support for pub run (#42726)
  if (args.contains('--launch-dds')) {
    RunCommand.launchDds = true;
  }
  String commandName;

  try {
    stopwatch.start();
    final runner = DartdevRunner(args);
    // Run can't be called with the '--disable-dartdev-analytics' flag, remove
    // it if it is contained in args.
    if (args.contains('--disable-dartdev-analytics')) {
      args = List.from(args)..remove('--disable-dartdev-analytics');
    }

    // Run also can't be called with '--launch-dds', remove it if it's
    // contained in args.
    if (args.contains('--launch-dds')) {
      args = List.from(args)..remove('--launch-dds');
    }

    // These flags have a format that can't be handled by package:args, so
    // while they are valid flags we'll assume the VM has verified them by this
    // point.
    args = args
        .where(
          (element) => !(element.contains('--observe') ||
              element.contains('--enable-vm-service')),
        )
        .toList();

    // Before calling to run, send the first ping to analytics to have the first
    // ping, as well as the command itself, running in parallel.
    if (analytics.enabled) {
      analytics.setSessionValue(flagsParam, getFlags(args));
      commandName = getCommandStr(args, runner.commands.keys.toList());
      // ignore: unawaited_futures
      analytics.sendEvent(eventCategory, commandName);
    }

    // If ... help pub ... is in the args list, remove 'help', and add '--help'
    // to the end of the list.  This will make it possible to use the help
    // command to access subcommands of pub such as `dart help pub publish`, see
    // https://github.com/dart-lang/sdk/issues/42965
    if (PubUtils.shouldModifyArgs(args, runner.commands.keys.toList())) {
      args = PubUtils.modifyArgs(args);
    }

    // Finally, call the runner to execute the command, see DartdevRunner.
    result = await runner.run(args);
  } catch (e, st) {
    if (e is UsageException) {
      io.stderr.writeln('$e');
      exitCode = 64;
    } else {
      // Set the exception and stack trace only for non-UsageException cases:
      exception = e;
      stackTrace = st;
      io.stderr.writeln('$e');
      io.stderr.writeln('$st');
      exitCode = 1;
    }
  } finally {
    stopwatch.stop();

    // Set the exitCode, if it wasn't set in the catch block above.
    exitCode ??= result ?? 0;

    // Send analytics before exiting
    if (analytics.enabled) {
      analytics.setSessionValue(exitCodeParam, exitCode);
      // ignore: unawaited_futures
      analytics.sendTiming(commandName, stopwatch.elapsedMilliseconds,
          category: 'commands');

      // And now send the exceptions and events to Google Analytics:
      if (exception != null) {
        // ignore: unawaited_futures
        analytics.sendException(
            '${exception.runtimeType}\n${sanitizeStacktrace(stackTrace)}',
            fatal: true);
      }

      await analytics.waitForLastPing(
          timeout: const Duration(milliseconds: 200));
    }

    // Set the enabled flag in the analytics object to true. Note: this will not
    // enable the analytics unless the disclosure was shown (terminal
    // detected), and the machine is not detected to be a bot.
    if (analytics.firstRun) {
      analytics.enabled = true;
    }
    analytics.close();
    VmInteropHandler.exit(exitCode);
  }
}

class DartdevRunner<int> extends CommandRunner {
  static const String dartdevDescription =
      'A command-line utility for Dart development';

  DartdevRunner(List<String> args) : super('dart', '$dartdevDescription.') {
    final bool verbose = args.contains('-v') || args.contains('--verbose');

    argParser.addFlag('verbose',
        abbr: 'v', negatable: false, help: 'Show additional command output.');
    argParser.addFlag('version',
        negatable: false, help: 'Print the Dart SDK version.');
    argParser.addFlag('enable-analytics',
        negatable: false, help: 'Enable anonymous analytics.');
    argParser.addFlag('disable-analytics',
        negatable: false, help: 'Disable anonymous analytics.');

    addExperimentalFlags(argParser, verbose);

    argParser.addFlag('diagnostics',
        negatable: false, help: 'Show tool diagnostic output.', hide: !verbose);

    // A hidden flag to disable analytics on this run, this constructor can be
    // called with this flag, but should be removed before run() is called as
    // the flag has not been added to all sub-commands.
    argParser.addFlag('disable-dartdev-analytics',
        negatable: false,
        help: 'Disable anonymous analytics for this `dart *` run',
        hide: true);

    // Another hidden flag used by the VM to indicate that DDS should be
    // launched. Should be removed for all commands other than `run`.
    argParser.addFlag('launch-dds',
        negatable: false, hide: true, help: 'Launch DDS.');

    addCommand(AnalyzeCommand());
    addCommand(CreateCommand(verbose: verbose));
    addCommand(CompileCommand());
    addCommand(FixCommand());
    addCommand(FormatCommand());
    addCommand(MigrateCommand(verbose: verbose));
    addCommand(PubCommand());
    addCommand(RunCommand(verbose: verbose));
    addCommand(TestCommand());
  }

  @override
  String get invocation =>
      'dart [<vm-flags>] <command|dart-file> [<arguments>]';

  void addExperimentalFlags(ArgParser argParser, bool verbose) {
    List<ExperimentalFeature> features = experimentalFeatures;

    Map<String, String> allowedHelp = {};
    for (ExperimentalFeature feature in features) {
      String suffix =
          feature.isEnabledByDefault ? ' (no-op - enabled by default)' : '';
      allowedHelp[feature.enableString] = '${feature.documentation}$suffix';
    }

    argParser.addMultiOption(
      experimentFlagName,
      valueHelp: 'experiment',
      allowed: features.map((feature) => feature.enableString),
      allowedHelp: verbose ? allowedHelp : null,
      help: 'Enable one or more experimental features.',
    );
  }

  @override
  Future<int> runCommand(ArgResults topLevelResults) async {
    assert(!topLevelResults.arguments.contains('--disable-dartdev-analytics'));

    if (topLevelResults.command == null &&
        topLevelResults.arguments.isNotEmpty) {
      final firstArg = topLevelResults.arguments.first;
      // If we make it this far, it means the VM couldn't find the file on disk.
      if (firstArg.endsWith('.dart')) {
        io.stderr.writeln(
            "Error when reading '$firstArg': No such file or directory.");
        // This is the exit code used by the frontend.
        VmInteropHandler.exit(254);
      }
    }

    isDiagnostics = topLevelResults['diagnostics'];

    final Ansi ansi = Ansi(Ansi.terminalSupportsAnsi);
    log = isDiagnostics
        ? Logger.verbose(ansi: ansi)
        : Logger.standard(ansi: ansi);

    if (topLevelResults.wasParsed(experimentFlagName)) {
      List<String> experimentIds = topLevelResults[experimentFlagName];
      for (ExperimentalFeature feature in experimentalFeatures) {
        // We allow default true flags, but complain when they are passed in.
        if (feature.isEnabledByDefault &&
            experimentIds.contains(feature.enableString)) {
          print("'${feature.enableString}' is now enabled by default; this "
              'flag is no longer required.');
        }
      }
    }

    return await super.runCommand(topLevelResults);
  }
}
