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

// Do not call exit() directly. Use VmInteropHandler.exit() instead.
import 'dart:async';
import 'dart:io' as io hide exit;
import 'dart:isolate';

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:meta/meta.dart';
import 'package:pub/pub.dart';
import 'package:unified_analytics/unified_analytics.dart';

import 'src/commands/analyze.dart';
import 'src/commands/build.dart';
import 'src/commands/compilation_server.dart';
import 'src/commands/compile.dart';
import 'src/commands/create.dart';
import 'src/commands/dart_mcp_server.dart';
import 'src/commands/debug_adapter.dart';
import 'src/commands/development_service.dart';
import 'src/commands/devtools.dart';
import 'src/commands/doc.dart';
import 'src/commands/fix.dart';
import 'src/commands/info.dart';
import 'src/commands/language_server.dart';
import 'src/commands/run.dart';
import 'src/commands/test.dart';
import 'src/commands/tooling_daemon.dart';
import 'src/core.dart';
import 'src/experiments.dart';
import 'src/unified_analytics.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.
Future<void> runDartdev(List<String> args, SendPort? port) async {
  int? exitCode = 1;
  try {
    VmInteropHandler.initialize(port);
    // Call the runner to execute the command; see DartdevRunner.
    final runner = DartdevRunner(args, vmArgs: io.Platform.executableArguments);
    exitCode = await runner.run(args);
  } on UsageException catch (e) {
    // TODO(sigurdm): It is unclear when a UsageException gets to here, and
    // when it is in DartdevRunner.runCommand.
    io.stderr.writeln('$e');
    exitCode = 64;
  } catch (e, st) {
    // Unexpected error encountered.
    io.stderr.writeln('An unexpected error was encountered by the Dart CLI.');
    io.stderr.writeln('Please file an issue at '
        'https://github.com/dart-lang/sdk/issues/new with the following '
        'details:\n');
    io.stderr.writeln("Invocation: 'dart ${args.join(' ')}'");
    io.stderr.writeln("Exception: '$e'");
    io.stderr.writeln('Stack Trace:');
    io.stderr.writeln(st.toString());
    exitCode = 255;
  } finally {
    VmInteropHandler.exit(exitCode);
  }
}

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

  @override
  final ArgParser argParser;

  final bool verbose;

  final List<String> vmEnabledExperiments;

  Analytics? _unifiedAnalytics;
  final bool _isAnalyticsTest;

  DartdevRunner(
    List<String> args, {
    Analytics? analyticsOverride,
    bool isAnalyticsTest = false,
    List<String> vmArgs = const [],
  })  : verbose = args.contains('-v') || args.contains('--verbose'),
        argParser = globalDartdevOptionsParser(
            verbose: args.contains('-v') || args.contains('--verbose')),
        vmEnabledExperiments = parseVmEnabledExperiments(vmArgs),
        _unifiedAnalytics = analyticsOverride,
        _isAnalyticsTest = isAnalyticsTest,
        super('dart', '$dartdevDescription.') {
    // The list of commands should be kept in sync with
    // `DartDevIsolate::ShouldParseCommand` in `runtime/bin/dartdev_isolate.cc`.
    addCommand(AnalyzeCommand(verbose: verbose));
    addCommand(CompilationServerCommand(verbose: verbose));
    final nativeAssetsExperimentEnabled =
        nativeAssetsEnabled(vmEnabledExperiments);
    if (nativeAssetsExperimentEnabled) {
      final recordUseExperimentEnabled = recordUseEnabled(vmEnabledExperiments);
      addCommand(BuildCommand(
        verbose: verbose,
        recordUseEnabled: recordUseExperimentEnabled,
      ));
    }
    addCommand(CompileCommand(
      verbose: verbose,
      nativeAssetsExperimentEnabled: nativeAssetsExperimentEnabled,
    ));
    addCommand(CreateCommand(verbose: verbose));
    addCommand(DebugAdapterCommand(verbose: verbose));
    addCommand(DevelopmentServiceCommand(verbose: verbose));
    addCommand(DevToolsCommand(verbose: verbose));
    addCommand(DocCommand(verbose: verbose));
    addCommand(FixCommand(verbose: verbose));
    addCommand(FormatCommand(
      verbose: verbose,
      category: CommandCategory.sourceCode.name,
    ));
    addCommand(InfoCommand(verbose: verbose));
    addCommand(LanguageServerCommand(verbose: verbose));
    addCommand(DartMCPServerCommand(verbose: verbose));
    addCommand(pubCommand(
      isVerbose: () => verbose,
      category: CommandCategory.project.name,
    ));
    addCommand(RunCommand(
      verbose: verbose,
      nativeAssetsExperimentEnabled: nativeAssetsExperimentEnabled,
    ));
    addCommand(TestCommand(
      nativeAssetsExperimentEnabled: nativeAssetsExperimentEnabled,
    ));
    addCommand(ToolingDaemonCommand(verbose: verbose));
  }

  @visibleForTesting
  Analytics get unifiedAnalytics => _unifiedAnalytics!;

  @override
  String get invocation =>
      'dart ${verbose ? '[vm-options] ' : ''}<command|dart-file> [arguments]';

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

  @override
  Future<int> runCommand(ArgResults topLevelResults) async {
    final stopwatch = Stopwatch()..start();

    // We don't want to run analytics when we're running in a CI environment
    // unless we're explicitly testing analytics for dartdev.
    final implicitlySuppressAnalytics = isBot() && !_isAnalyticsTest;
    bool suppressAnalytics = !topLevelResults.flag('analytics') ||
        topLevelResults.flag('suppress-analytics') ||
        implicitlySuppressAnalytics;

    if (topLevelResults.wasParsed('analytics')) {
      io.stderr.writeln(
          '`--[no-]analytics` is deprecated.  Use `--suppress-analytics` '
          'to disable analytics for one run instead.');
    }
    final enableAnalytics = topLevelResults.flag('enable-analytics');
    final disableAnalytics = topLevelResults.flag('disable-analytics');

    if (!implicitlySuppressAnalytics &&
        suppressAnalytics &&
        (enableAnalytics || disableAnalytics)) {
      // This isn't an error if we're implicitly disabling analytics because
      // we're running in a CI environment.
      io.stderr.writeln('`--suppress-analytics` cannot be used with either'
          ' `--enable-analytics` or `--disable-analytics`.');
      return 254;
    }
    // The Analytics instance used to report information back to Google Analytics;
    // see lib/src/unified_analytics.dart.
    _unifiedAnalytics ??= createUnifiedAnalytics(
      disableAnalytics: suppressAnalytics,
    );

    // If we have not printed the analytics notification to stdout, the user is
    // on a terminal, and the machine is not a bot, then print the disclosure.
    bool analyticsMessagePrinted = false;
    if (unifiedAnalytics.shouldShowMessage &&
        io.stdout.hasTerminal &&
        !isBot()) {
      print(unifiedAnalytics.getConsentMessage);
      unifiedAnalytics.clientShowedMessage();
      analyticsMessagePrinted = true;
    }

    // When `--disable-analytics` or `--enable-analytics` are called we perform
    // the respective intention and print any notices to standard out and exit.
    if (disableAnalytics) {
      // Disable sending data via the unified analytics package.
      await unifiedAnalytics.setTelemetry(false);
      await unifiedAnalytics.close();

      // Alert the user that analytics has been disabled.
      print(analyticsDisabledNoticeMessage);
      return 0;
    } else if (enableAnalytics) {
      // Enable sending data via the unified analytics package.
      await unifiedAnalytics.setTelemetry(true);
      await unifiedAnalytics.close();

      // Alert the user again that data will be collected.
      if (!analyticsMessagePrinted) {
        print(unifiedAnalytics.getConsentMessage);
      }
      return 0;
    }

    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.
        return 254;
      }
    }

    if (topLevelResults.flag('diagnostics')) {
      log = Logger.verbose(ansi: ansi);
    }

    late final List<String> experimentErrors =
        validateExperiments(vmEnabledExperiments);
    if (experimentErrors.isNotEmpty) {
      experimentErrors.forEach(io.stderr.writeln);
      return 254;
    }

    var command = topLevelResults.command;
    final commandNames = [];
    while (command != null) {
      commandNames.add(command.name);
      if (command.command == null) break;
      command = command.command;
    }

    // The exit code for the dartdev process; null indicates that it has not 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.
    try {
      exitCode = await super.runCommand(topLevelResults);
      if (unifiedAnalytics.telemetryEnabled) {
        // Send the event to analytics
        final path = commandNames.join('/');
        final experiments = topLevelResults.enabledExperiments
          ..sort((a, b) => a.compareTo(b));
        unifiedAnalytics.send(
          Event.dartCliCommandExecuted(
            name: path,
            enabledExperiments: experiments.join(','),
          ),
        );
      }
    } on UsageException catch (e) {
      io.stderr.writeln('$e');
      exitCode = 64;
    } catch (e, st) {
      // Set the exception and stack trace only for non-UsageException cases:
      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 ??= 0;
      await unifiedAnalytics.close();
    }

    return exitCode;
  }
}
