// 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:usage/usage.dart';

import 'src/analytics.dart';
import 'src/commands/analyze.dart';
import 'src/commands/compile.dart';
import 'src/commands/compile_server_shutdown.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/language_server.dart';
import 'src/commands/migrate.dart';
import 'src/commands/run.dart';
import 'src/commands/test.dart';
import 'src/core.dart';
import 'src/events.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.
Future<void> runDartdev(List<String> args, SendPort? port) async {
  int? exitCode = 1;
  try {
    VmInteropHandler.initialize(port);

    // TODO(sigurdm): Remove when top-level pub is removed.
    if (args[0] == '__deprecated_pub') {
      // This is the entry-point supporting the top-level `pub` script.
      // ignore: deprecated_member_use
      exitCode = await deprecatedpubCommand().run(args.skip(1));
    } else {
      if (args.contains('run')) {
        // 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') ||
                  element.contains('--devtools')),
            )
            .toList();
      }

      // Finally, call the runner to execute the command; see DartdevRunner.
      final runner = DartdevRunner(args);
      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 = ArgParser(
    usageLineLength: dartdevUsageLineLength,
    allowTrailingOptions: false,
  );

  final bool verbose;

  late Analytics _analytics;

  DartdevRunner(List<String> args)
      : verbose = args.contains('-v') || args.contains('--verbose'),
        super('dart', '$dartdevDescription.') {
    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 analytics.');
    argParser.addFlag('disable-analytics',
        negatable: false, help: 'Disable analytics.');

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

    argParser.addFlag(
      'analytics',
      negatable: true,
      help: 'Disable analytics for this `dart *` run',
      hide: true,
    );

    addCommand(AnalyzeCommand(verbose: verbose));
    addCommand(CreateCommand(verbose: verbose));
    addCommand(DebugAdapterCommand(verbose: verbose));
    addCommand(CompileCommand(verbose: verbose));
    addCommand(DocCommand(verbose: verbose));
    addCommand(DevToolsCommand(
      verbose: verbose,
    ));
    addCommand(FixCommand(verbose: verbose));
    addCommand(FormatCommand(verbose: verbose));
    addCommand(LanguageServerCommand(verbose: verbose));
    addCommand(MigrateCommand(verbose: verbose));
    addCommand(
      pubCommand(
        analytics: PubAnalytics(
          () => analytics,
          dependencyKindCustomDimensionName: dependencyKindCustomDimensionName,
        ),
        isVerbose: () => verbose,
      ),
    );
    addCommand(RunCommand(verbose: verbose));
    addCommand(TestCommand());
    addCommand(CompileServerShutdownCommand(verbose: verbose));
  }

  @visibleForTesting
  Analytics get analytics => _analytics;

  @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();
    // The Analytics instance used to report information back to Google Analytics;
    // see lib/src/analytics.dart.
    _analytics = createAnalyticsInstance(
      topLevelResults.wasParsed('analytics')
          ? !topLevelResults['analytics']
          : false,
    );

    // 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 as DartdevAnalytics).disclosureShownOnTerminal &&
        io.stdout.hasTerminal &&
        !isBot()) {
      print(analyticsNoticeOnFirstRunMessage);
      (analytics as DartdevAnalytics).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 (topLevelResults['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 has been disabled.
      print(analyticsDisabledNoticeMessage);
      return 0;
    } else if (topLevelResults['enable-analytics']) {
      analytics.enabled = true;

      // Alert the user again that data will be collected.
      print(analyticsNoticeOnFirstRunMessage);
      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;
    }

    final path = commandNames.join('/');
    // Send the screen view to analytics
    unawaited(
      analytics.sendScreenView(path, parameters:
          // Starts a new analytics session.
          // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#sc
          {'sc': 'start'}),
    );

    // 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.
    Object? exception;
    StackTrace? stackTrace;
    try {
      exitCode = await super.runCommand(topLevelResults);

      if (analytics.enabled) {
        // Send the event to analytics
        unawaited(
          sendUsageEvent(
            analytics,
            path,
            exitCode: exitCode,
            commandFlags:
                // This finds the options that where explicitly given to the command
                // (and not for an eventual subcommand) without including the actual
                // value.
                //
                // Note that this will also conflate short-options and long-options.
                command?.options.where(command.wasParsed).toList() ??
                    const <String>[],
            specifiedExperiments: topLevelResults.enabledExperiments,
          ),
        );
      }
    } on UsageException catch (e) {
      io.stderr.writeln('$e');
      exitCode = 64;
    } catch (e, st) {
      // 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();

      if (analytics.enabled) {
        unawaited(
          analytics.sendTiming(
            path,
            stopwatch.elapsedMilliseconds,
            category: 'commands',
          ),
        );
      }

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

      // Send analytics before exiting
      if (analytics.enabled) {
        // And now send the exceptions and events to Google Analytics:
        if (exception != null) {
          unawaited(
            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();
    }

    return exitCode;
  }
}
