// 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' hide Runtime;
import 'src/core.dart';
import 'src/experiments.dart';
import 'src/sdk.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) {
      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 {
  @override
  final ArgParser argParser =
      ArgParser(usageLineLength: dartdevUsageLineLength);

  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(verbose: verbose));
    addCommand(MigrateCommand(
      verbose: verbose,
      hidden: Runtime.runtime.stableChannel,
    ));
    addCommand(PubCommand());
    addCommand(RunCommand(verbose: verbose));
    addCommand(TestCommand());
  }

  @override
  String get usageFooter =>
      'See https://dart.dev/tools/dart-tool for detailed documentation.';

  @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',
      allowedHelp: verbose ? allowedHelp : null,
      help: 'Enable one or more experimental features '
          '(see dart.dev/go/experiments).',
      hide: !verbose,
    );
  }

  @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);
  }
}
