// 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/debug_adapter.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
  late 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.') {
    addCommand(AnalyzeCommand(verbose: verbose));
    addCommand(CompilationServerCommand(verbose: verbose));
    final nativeAssetsExperimentEnabled =
        nativeAssetsEnabled(vmEnabledExperiments);
    if (nativeAssetsExperimentEnabled) {
      addCommand(BuildCommand(verbose: verbose));
    }
    addCommand(CompileCommand(
      verbose: verbose,
      nativeAssetsExperimentEnabled: nativeAssetsExperimentEnabled,
    ));
    addCommand(CreateCommand(verbose: verbose));
    addCommand(DebugAdapterCommand(verbose: verbose));
    addCommand(DevToolsCommand(verbose: verbose));
    addCommand(DocCommand(verbose: verbose));
    addCommand(FixCommand(verbose: verbose));
    addCommand(FormatCommand(verbose: verbose));
    addCommand(InfoCommand(verbose: verbose));
    addCommand(LanguageServerCommand(verbose: verbose));
    addCommand(pubCommand(isVerbose: () => verbose));
    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['analytics'] ||
        topLevelResults['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['enable-analytics'];
    final disableAnalytics = topLevelResults['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['diagnostics']) {
      log = Logger.verbose(ansi: ansi);
    }

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