// Copyright (c) 2014, 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:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';

import 'package:analysis_server/protocol/protocol_constants.dart'
    show PROTOCOL_VERSION;
import 'package:analysis_server/src/analytics/analytics_manager.dart';
import 'package:analysis_server/src/legacy_analysis_server.dart';
import 'package:analysis_server/src/lsp/lsp_socket_server.dart';
import 'package:analysis_server/src/server/crash_reporting.dart';
import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/detachable_filesystem_manager.dart';
import 'package:analysis_server/src/server/dev_server.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/server/error_notifier.dart';
import 'package:analysis_server/src/server/features.dart';
import 'package:analysis_server/src/server/http_server.dart';
import 'package:analysis_server/src/server/isolate_analysis_server.dart';
import 'package:analysis_server/src/server/lsp_stdio_server.dart';
import 'package:analysis_server/src/server/sdk_configuration.dart';
import 'package:analysis_server/src/server/stdio_server.dart';
import 'package:analysis_server/src/services/correction/assist_internal.dart';
import 'package:analysis_server/src/services/correction/fix_internal.dart';
import 'package:analysis_server/src/services/perf_witness/perf_witness.dart';
import 'package:analysis_server/src/session_logger/session_logger.dart';
import 'package:analysis_server/src/socket_server.dart';
import 'package:analysis_server/src/status/performance_logger.dart';
import 'package:analysis_server/src/utilities/env.dart' as env;
import 'package:analysis_server/src/utilities/request_statistics.dart';
import 'package:analysis_server/starter.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/file_instrumentation.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/util/sdk.dart';
import 'package:args/args.dart';
import 'package:linter/src/rules.dart' as linter;
import 'package:telemetry/crash_reporting.dart';
import 'package:unified_analytics/unified_analytics.dart';

import '../utilities/usage_tracking/usage_tracking.dart';

/// The [Driver] class represents a single running instance of the analysis
/// server application.  It is responsible for parsing command line options
/// and starting the HTTP and/or stdio servers.
class Driver implements ServerStarter {
  /// The name of the application that is used to start a server.
  static const binaryName = 'analysis_server';

  /// The name of the option used to set the identifier for the client.
  static const String clientIdOption = 'client-id';

  /// The name of the option used to set the version for the client.
  static const String clientVersionOption = 'client-version';

  /// The name of the option used to disable exception handling.
  static const String disableServerExceptionHandlingOption =
      'disable-server-exception-handling';

  /// The name of the option to disable the completion feature.
  static const String disableServerFeatureCompletionOption =
      'disable-server-feature-completion';

  /// The name of the option to disable the search feature.
  static const String disableServerFeatureSearchOption =
      'disable-server-feature-search';

  /// The name of the option to disable the debouncing of `server.status`
  /// notifications.
  static const String disableStatusNotificationDebouncingOption =
      'disable-status-notification-debouncing';

  /// The name of the option to prevent exceptions during analysis from being
  /// silent.
  static const String disableSilentAnalysisExceptionsOption =
      'disable-silent-analysis-exceptions';

  /// The name of the multi-option to enable one or more experiments.
  static const String enableExperimentOption = 'enable-experiment';

  /// The name of the option used to print usage information.
  static const String helpFlag = 'help';

  /// The name of the flag used to configure reporting legacy analytics.
  static const String analyticsFlag = 'analytics';

  /// The name of the flag used to suppress legacy analytics for this session.
  static const String suppressAnalyticsFlag = 'suppress-analytics';

  /// The name of the option used to cause instrumentation to also be written to
  /// a local file.
  static const String protocolTrafficLogOption = 'protocol-traffic-log';
  static const String protocolTrafficLogAliasOption =
      'instrumentation-log-file';

  /// The name of the option used to cause a log of the session to be written to
  /// a file.
  static const String sessionLogOption = 'session-log';

  /// The name of the option used to cause selected data from the analysis
  /// server to be written to a file.
  static const String performanceLogOption = 'performance-log';

  /// The name of the option used to specify if [print] should print to the
  /// console instead of being intercepted.
  static const String internalPrintToConsoleOption =
      'internal-print-to-console';

  /// The name of the option used to describe the new analysis driver logger.
  static const String analysisDriverLogOption = 'analysis-driver-log';
  static const String analysisDriverLogAliasOption = 'new-analysis-driver-log';

  /// The name of the option for specifying the http diagnostic port.
  /// If specified, users can review server status and performance information
  /// by opening a web browser on `http://localhost:<port>`.
  static const String diagnosticPortOption = 'diagnostic-port';
  static const String diagnosticPortAliasOption = 'port';

  /// The name of the option used to specify the path to the SDK.
  static const String dartSdkOption = 'dart-sdk';
  static const String dartSdkAliasOption = 'sdk';

  /// The name of the option used to specify the path to the data cache.
  static const String cacheFolderOption = 'cache';

  /// The name of the option used to specify the path to the package config file
  /// override.
  static const String packagesFileOption = 'packages';

  /// The name of the option used to specify a forced protocol version that the
  /// server will report to the client.
  static const String reportProtocolVersionOption = 'report-protocol-version';

  /// The name of the option specifying the server protocol to use.
  static const String serverProtocolOption = 'protocol';
  static const String protocolAnalyzer = 'analyzer';
  static const String protocolLsp = 'lsp';

  /// The name of the flag to use the Language Server Protocol (LSP).
  static const String useLspFlag = 'lsp';

  /// The name of the flag used to specify a directory to analyze in order to
  /// train an analysis server snapshot.
  static const String trainUsingOption = 'train-using';

  /// Flag to disable the persistent byte store.
  static const String disableFileByteStoreOption = 'disable-file-byte-store';

  /// The name of the flag to use the experimental single-file byte store.
  static const String useSingleFileByteStoreOption =
      'use-single-file-byte-store';

  /// The name of the flag to enable fine-grained dependencies.
  static const String withFineDependenciesOption = 'with-fine-dependencies';

  static const String pluginsFlag = 'plugins';

  /// The builder for attachments that should be included into crash reports.
  CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder =
      CrashReportingAttachmentsBuilder.empty;

  /// An optional manager to handle file systems which may not always be
  /// available.
  DetachableFileSystemManager? detachableFileSystemManager;

  /// The instrumentation service that is to be used by the analysis server.
  late final InstrumentationService _instrumentationService;

  /// The session logger.
  late final SessionLogger _sessionLogger;

  /// Use the given command-line [arguments] to start this server.
  ///
  /// If [sendPort] is not null, assumes this is launched in an isolate and will
  /// connect to the original isolate via an isolate channel.
  @override
  void start(
    List<String> arguments, {
    SendPort? sendPort,
    bool defaultToLsp = false,
  }) async {
    await startPerfWitness();

    var sessionStartTime = DateTime.now();
    var parser = createArgParser(defaultToLsp: defaultToLsp);
    var results = parser.parse(arguments);

    var analysisServerOptions = AnalysisServerOptions();
    analysisServerOptions.newAnalysisDriverLog =
        results.option(analysisDriverLogOption) ??
        results.option(analysisDriverLogAliasOption);
    if (results.wasParsed(useLspFlag)) {
      analysisServerOptions.useLanguageServerProtocol = results.flag(
        useLspFlag,
      );
    } else {
      analysisServerOptions.useLanguageServerProtocol =
          results.option(serverProtocolOption) == protocolLsp;
    }
    // For clients that don't supply their own identifier, use a default based
    // on whether the server will run in LSP mode or not.
    var clientId =
        results.option(clientIdOption) ??
        (analysisServerOptions.useLanguageServerProtocol
            ? 'unknown.client.lsp'
            : 'unknown.client.classic');
    analysisServerOptions.clientId = clientId;
    analysisServerOptions.clientVersion = results.option(clientVersionOption);
    analysisServerOptions.cacheFolder = results.option(cacheFolderOption);
    analysisServerOptions.useSingleFileByteStore = results.flag(
      useSingleFileByteStoreOption,
    );
    analysisServerOptions.packagesFile = results.option(packagesFileOption);
    analysisServerOptions.reportProtocolVersion = results.option(
      reportProtocolVersionOption,
    );
    analysisServerOptions.withFineDependencies = results.flag(
      withFineDependenciesOption,
    );

    analysisServerOptions.enabledExperiments = results.multiOption(
      enableExperimentOption,
    );

    // Read in any per-SDK overrides specified in <sdk>/config/settings.json.
    var sdkConfig = SdkConfiguration.readFromSdk();
    analysisServerOptions.configurationOverrides = sdkConfig;

    analysisServerOptions.usePlugins = results.flag(pluginsFlag);

    var defaultSdkPath = _getSdkPath(results);
    var dartSdkManager = DartSdkManager(defaultSdkPath);

    // TODO(brianwilkerson): It would be nice to avoid creating an SDK that
    // can't be re-used, but the SDK is needed to create a package map provider
    // in the case where we need to run `pub` in order to get the package map.
    var defaultSdk = _createDefaultSdk(defaultSdkPath);

    // Create the analytics manager.

    var tool =
        env.topLevelTool ??
        switch (clientId) {
          'VS-Code' || 'VS-Code-Remote' => DashTool.vscodePlugins,
          'IntelliJ-IDEA' => DashTool.intellijPlugins,
          'Android-Studio' => DashTool.androidStudioPlugins,
          _ => null,
        };

    // Analytics (legacy, and unified).
    var disableAnalyticsForSession =
        tool == null ||
        areAnalyticsSuppressed() ||
        results.flag(suppressAnalyticsFlag) ||
        results.wasParsed(trainUsingOption);

    var analytics = disableAnalyticsForSession
        ? NoOpAnalytics()
        : _createAnalytics(defaultSdk, defaultSdkPath, tool);
    var analyticsManager = AnalyticsManager(analytics);

    bool shouldSendCallback() {
      // Check sdkConfig to optionally force reporting on.
      if (sdkConfig.crashReportingForceEnabled == true) {
        return true;
      }

      // Reuse the unified_analytics consent mechanism to determine whether
      // we can send a crash report.
      return analyticsManager.analytics.okToSend;
    }

    // Crash reporting

    // Use sdkConfig to optionally override analytics settings.
    var crashProductId = sdkConfig.crashReportingId ?? 'Dart_analysis_server';
    var crashReportSender = CrashReportSender.prod(
      crashProductId,
      shouldSendCallback,
    );

    {
      var disableCompletion = results.flag(
        disableServerFeatureCompletionOption,
      );
      var disableSearch = results.flag(disableServerFeatureSearchOption);
      if (disableCompletion || disableSearch) {
        analysisServerOptions.featureSet = FeatureSet(
          completion: !disableCompletion,
          search: !disableSearch,
        );
      }
    }

    if (results.flag(helpFlag)) {
      _printUsage(parser, fromHelp: true);
      return;
    }

    // Record the start of the session.
    analyticsManager.startUp(
      time: sessionStartTime,
      arguments: _getArgumentsForAnalytics(results),
      clientId: clientId,
      clientVersion: analysisServerOptions.clientVersion,
    );

    // Initialize the instrumentation service.
    var logFilePath =
        results.option(protocolTrafficLogOption) ??
        results.option(protocolTrafficLogAliasOption);
    var allInstrumentationServices = <InstrumentationService>[];
    if (logFilePath != null) {
      _rollLogFiles(logFilePath, 5);
      allInstrumentationServices.add(
        InstrumentationLogAdapter(
          FileInstrumentationLogger(logFilePath),
          watchEventExclusionFiles: {logFilePath},
        ),
      );
    }

    var errorNotifier = ErrorNotifier();
    allInstrumentationServices.add(errorNotifier);
    allInstrumentationServices.add(
      CrashReportingInstrumentation(crashReportSender),
    );
    _instrumentationService = MulticastInstrumentationService(
      allInstrumentationServices,
    );

    // Initialize the session logging service.
    var sessionLogFilePath = results.option(sessionLogOption);
    _sessionLogger = SessionLogger(filePath: sessionLogFilePath);
    _sessionLogger.normalizer.addReplacementsForPath(
      defaultSdkPath,
      'dartSdkRoot',
    );

    // Log the command-line.
    _instrumentationService.logVersion(
      results.option(trainUsingOption) != null
          ? 'training-0'
          : _readUuid(_instrumentationService, _sessionLogger),
      analysisServerOptions.clientId ?? '',
      analysisServerOptions.clientVersion ?? '',
      PROTOCOL_VERSION,
      defaultSdk.languageVersion.toString(),
    );
    AnalysisEngine.instance.instrumentationService = _instrumentationService;
    _sessionLogger.logCommandLine(arguments: arguments);

    int? diagnosticServerPort;
    var portValue =
        results.option(diagnosticPortOption) ??
        results.option(diagnosticPortAliasOption);
    if (portValue != null) {
      try {
        diagnosticServerPort = int.parse(portValue);
      } on FormatException {
        print('Invalid port number: $portValue');
        print('');
        _printUsage(parser);
        exitCode = 1;
        return;
      }
    }

    PerformanceLogger? performanceLogger;
    var performanceLogFilePath = results.option(performanceLogOption);
    if (performanceLogFilePath != null) {
      _rollLogFiles(performanceLogFilePath, 5);
      performanceLogger = PerformanceLogger(performanceLogFilePath);
    }

    // TODO(brianwilkerson): Pass the following value to the server and
    // implement the debouncing when it hasn't been disabled.
    // var disableDebouncing = results[DISABLE_STATUS_NOTIFICATION_DEBOUNCING] as bool;

    var environment = env.map(
      tool: tool,
      suppressAnalytics: disableAnalyticsForSession,
    );

    if (analysisServerOptions.useLanguageServerProtocol) {
      if (sendPort != null) {
        throw UnimplementedError(
          'Isolate usage not implemented for LspAnalysisServer',
        );
      }
      startLspServer(
        results,
        analysisServerOptions,
        dartSdkManager,
        analyticsManager,
        _instrumentationService,
        _sessionLogger,
        diagnosticServerPort,
        errorNotifier,
        performanceLogger,
        environment,
      );
    } else {
      startAnalysisServer(
        results,
        analysisServerOptions,
        parser,
        dartSdkManager,
        analyticsManager,
        crashReportingAttachmentsBuilder,
        _instrumentationService,
        _sessionLogger,
        RequestStatisticsHelper(),
        diagnosticServerPort,
        errorNotifier,
        sendPort,
        performanceLogger,
        environment,
      );
    }

    configureMemoryUsageTracking(
      arguments,
      (memoryUsageEvent) => analyticsManager.sendMemoryUsage(memoryUsageEvent),
    );
  }

  void startAnalysisServer(
    ArgResults results,
    AnalysisServerOptions analysisServerOptions,
    ArgParser parser,
    DartSdkManager dartSdkManager,
    AnalyticsManager analyticsManager,
    CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
    InstrumentationService instrumentationService,
    SessionLogger sessionLogger,
    RequestStatisticsHelper requestStatistics,
    int? diagnosticServerPort,
    ErrorNotifier errorNotifier,
    SendPort? sendPort,
    PerformanceLogger? performanceLogger,
    Map<String, String>? environment,
  ) {
    var capture = results.flag(disableServerExceptionHandlingOption)
        ? (_, _, Function f, {void Function(String)? print}) => f()
        : _captureExceptions;
    var trainDirectory = results.option(trainUsingOption);
    if (trainDirectory != null) {
      if (!FileSystemEntity.isDirectorySync(trainDirectory)) {
        print("Training directory '$trainDirectory' not found.\n");
        exitCode = 1;
        return;
      }
    }
    linter.registerLintRules();
    registerBuiltInAssistGenerators();
    registerBuiltInFixGenerators();

    var diagnosticServer = _DiagnosticServerImpl();

    //
    // Create the sockets and start listening for requests.
    //
    var socketServer = SocketServer(
      analysisServerOptions,
      dartSdkManager,
      crashReportingAttachmentsBuilder,
      instrumentationService,
      sessionLogger,
      requestStatistics,
      diagnosticServer,
      analyticsManager,
      detachableFileSystemManager,
      performanceLogger,
      environment: environment,
    );

    diagnosticServer.httpServer = HttpAnalysisServer(socketServer);
    if (diagnosticServerPort != null) {
      diagnosticServer.startOnPort(diagnosticServerPort);
    }

    if (trainDirectory != null) {
      if (sendPort != null) {
        throw UnimplementedError(
          'isolate usage not supported for DevAnalysisServer',
        );
      }
      var tempDriverDir = Directory.systemTemp.createTempSync(
        'analysis_server_',
      );
      analysisServerOptions.cacheFolder = tempDriverDir.path;
      analysisServerOptions.disableFileByteStore = results.flag(
        disableFileByteStoreOption,
      );

      var devServer = DevAnalysisServer(socketServer);
      devServer.initServer();

      () async {
        // We first analyze code with an empty driver cache.
        print('Analyzing with an empty driver cache:');
        var exitCode = await devServer.processDirectories([trainDirectory]);
        if (exitCode != 0) exit(exitCode);

        print('');

        // Then again with a populated cache.
        print('Analyzing with a populated driver cache:');
        exitCode = await devServer.processDirectories([trainDirectory]);
        if (exitCode != 0) exit(exitCode);

        diagnosticServer.httpServer.close();
        await instrumentationService.shutdown();
        unawaited(socketServer.analysisServer!.shutdown());

        try {
          tempDriverDir.deleteSync(recursive: true);
        } catch (_) {
          // Ignore any exception.
        }

        exit(exitCode);
      }();
    } else {
      capture(
        instrumentationService,
        sessionLogger,
        () {
          Future<void> serveResult;
          if (sendPort == null) {
            var stdioServer = StdioAnalysisServer(socketServer);
            serveResult = stdioServer.serveStdio();
          } else {
            var isolateAnalysisServer = IsolateAnalysisServer(socketServer);
            serveResult = isolateAnalysisServer.serveIsolate(sendPort);
          }
          errorNotifier.server = socketServer.analysisServer;
          if (results.flag(disableSilentAnalysisExceptionsOption)) {
            errorNotifier.sendSilentExceptionsToClient = true;
          }
          serveResult.then((_) async {
            diagnosticServer.httpServer.close();
            await instrumentationService.shutdown();
            unawaited(socketServer.analysisServer!.shutdown());
            if (sendPort == null) exit(0);
          });
        },
        print: results.flag(internalPrintToConsoleOption)
            ? null
            : diagnosticServer.httpServer.recordPrint,
      );
    }
  }

  void startLspServer(
    ArgResults args,
    AnalysisServerOptions analysisServerOptions,
    DartSdkManager dartSdkManager,
    AnalyticsManager analyticsManager,
    InstrumentationService instrumentationService,
    SessionLogger sessionLogger,
    int? diagnosticServerPort,
    ErrorNotifier errorNotifier,
    PerformanceLogger? performanceLogger,
    Map<String, String>? environment,
  ) {
    var capture = args.flag(disableServerExceptionHandlingOption)
        ? (_, _, Function f, {void Function(String)? print}) => f()
        : _captureExceptions;

    linter.registerLintRules();
    registerBuiltInAssistGenerators();
    registerBuiltInFixGenerators();

    var diagnosticServer = _DiagnosticServerImpl();

    var socketServer = LspSocketServer(
      analysisServerOptions,
      diagnosticServer,
      analyticsManager,
      dartSdkManager,
      instrumentationService,
      sessionLogger,
      detachableFileSystemManager,
      performanceLogger,
      environment: environment,
    );
    diagnosticServer.httpServer = HttpAnalysisServer(socketServer);

    if (diagnosticServerPort != null) {
      diagnosticServer.startOnPort(diagnosticServerPort);
    }

    capture(instrumentationService, sessionLogger, () {
      var stdioServer = LspStdioAnalysisServer(socketServer);
      var serveResult = stdioServer.serveStdio();
      errorNotifier.server = socketServer.analysisServer;
      if (args.flag(disableSilentAnalysisExceptionsOption)) {
        errorNotifier.sendSilentExceptionsToClient = true;
      }
      serveResult.then((_) {
        // Only shutdown the server and exit if the server is not already
        // handling the shutdown.
        if (!socketServer.analysisServer!.willExit) {
          unawaited(socketServer.analysisServer!.shutdown());
          exit(0);
        }
      });
    });
  }

  /// Execute the given [callback] within a zone that will capture any unhandled
  /// exceptions and both report them to the client and send them to the given
  /// instrumentation [service]. If a [print] function is provided, then also
  /// capture any data printed by the callback and redirect it to the function.
  void _captureExceptions(
    InstrumentationService service,
    SessionLogger sessionLogger,
    void Function() callback, {
    void Function(String line)? print,
  }) {
    void errorFunction(
      Zone self,
      ZoneDelegate parent,
      Zone zone,
      Object exception,
      StackTrace stackTrace,
    ) {
      service.logException(exception, stackTrace);
      sessionLogger.logException(exception: exception, stackTrace: stackTrace);
      throw exception;
    }

    var printFunction = print == null
        ? null
        : (Zone self, ZoneDelegate parent, Zone zone, String line) {
            // Note: we don't pass the line on to stdout, because that is
            // reserved for communication to the client.
            print(line);
          };
    var zoneSpecification = ZoneSpecification(
      handleUncaughtError: errorFunction,
      print: printFunction,
    );
    return runZoned(callback, zoneSpecification: zoneSpecification);
  }

  /// Create the `Analytics` instance to be used to report analytics.
  Analytics _createAnalytics(
    DartSdk dartSdk,
    String dartSdkPath,
    DashTool tool,
  ) {
    // TODO(brianwilkerson): Find out whether there's a way to get the channel
    //  without running `flutter channel`.
    var pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
    var flutterSdkRoot = pathContext.dirname(
      pathContext.dirname(pathContext.dirname(dartSdkPath)),
    );
    var flutterVersionFile = PhysicalResourceProvider.INSTANCE.getFile(
      pathContext.join(flutterSdkRoot, 'version'),
    );
    String? flutterVersion;
    try {
      flutterVersion = flutterVersionFile.readAsStringSync();
    } catch (exception) {
      // If we can't read the file, ignore it.
    }
    return Analytics(
      tool: tool,
      dartVersion: dartSdk.sdkVersion,
      // flutterChannel: '',
      flutterVersion: flutterVersion,
    );
  }

  DartSdk _createDefaultSdk(String defaultSdkPath) {
    var resourceProvider = PhysicalResourceProvider.INSTANCE;
    return FolderBasedDartSdk(
      resourceProvider,
      resourceProvider.getFolder(defaultSdkPath),
    );
  }

  /// Constructs a uuid combining the current date and a random integer.
  String _generateUuidString() {
    var millisecondsSinceEpoch = DateTime.now().millisecondsSinceEpoch;
    var random = Random().nextInt(0x3fffffff);
    return '$millisecondsSinceEpoch$random';
  }

  /// Return a list of the known command-line arguments that were parsed when
  /// creating the given [results]. We return only the names of the arguments,
  /// not the values of the arguments, in order to prevent the collection of any
  /// PII.
  List<String> _getArgumentsForAnalytics(ArgResults results) {
    // The arguments that are literal strings are deprecated and no longer read
    // from, but we still want to know if clients are using them.
    var knownArguments = [
      analyticsFlag,
      cacheFolderOption,
      clientIdOption,
      clientVersionOption,
      'completion-model',
      'dartpad',
      dartSdkOption,
      dartSdkAliasOption,
      diagnosticPortOption,
      diagnosticPortAliasOption,
      disableServerExceptionHandlingOption,
      disableServerFeatureCompletionOption,
      disableServerFeatureSearchOption,
      disableSilentAnalysisExceptionsOption,
      disableStatusNotificationDebouncingOption,
      'enable-completion-model',
      'enable-experiment',
      'enable-instrumentation',
      'file-read-mode',
      helpFlag,
      'ignore-unrecognized-flags',
      internalPrintToConsoleOption,
      packagesFileOption,
      'preview-dart-2',
      protocolTrafficLogOption,
      protocolTrafficLogAliasOption,
      reportProtocolVersionOption,
      serverProtocolOption,
      sessionLogOption,
      suppressAnalyticsFlag,
      trainUsingOption,
      'useAnalysisHighlight2',
      useLspFlag,
      'use-new-relevance',
      'use-fasta-parser',
      disableFileByteStoreOption,
      useSingleFileByteStoreOption,
      withFineDependenciesOption,
    ];
    return knownArguments
        .where((argument) => results.wasParsed(argument))
        .toList();
  }

  String _getSdkPath(ArgResults args) {
    String? sdkPath;

    void tryCandidateArgument(String argumentName) {
      var argumentValue = args[argumentName];
      if (sdkPath == null && argumentValue is String) {
        sdkPath = argumentValue;
      }
    }

    tryCandidateArgument(dartSdkOption);
    tryCandidateArgument(dartSdkAliasOption);
    var sdkPath2 = sdkPath ?? getSdkPath();

    var pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
    return pathContext.normalize(pathContext.absolute(sdkPath2));
  }

  /// Print information about how to use the server.
  void _printUsage(ArgParser parser, {bool fromHelp = false}) {
    print('Usage: $binaryName [flags]');
    print('');
    print('Supported flags are:');
    print(parser.usage);
  }

  /// Read the UUID from disk, generating and storing a new one if necessary.
  String _readUuid(
    InstrumentationService service,
    SessionLogger sessionLogger,
  ) {
    var instrumentationLocation = PhysicalResourceProvider.INSTANCE
        .getStateLocation('.instrumentation');
    if (instrumentationLocation == null) {
      return _generateUuidString();
    }
    var uuidFile = File(instrumentationLocation.getChild('uuid.txt').path);
    try {
      if (uuidFile.existsSync()) {
        var uuid = uuidFile.readAsStringSync();
        if (uuid.length > 5) {
          return uuid;
        }
      }
    } catch (exception, stackTrace) {
      service.logException(exception, stackTrace);
      sessionLogger.logException(exception: exception, stackTrace: stackTrace);
    }
    var uuid = _generateUuidString();
    try {
      uuidFile.parent.createSync(recursive: true);
      uuidFile.writeAsStringSync(uuid);
    } catch (exception, stackTrace) {
      service.logException(exception, stackTrace);
      sessionLogger.logException(exception: exception, stackTrace: stackTrace);
      // Slightly alter the uuid to indicate it was not persisted
      uuid = 'temp-$uuid';
    }
    return uuid;
  }

  /// Create and return the parser used to parse the command-line arguments.
  static ArgParser createArgParser({
    int? usageLineLength,
    bool includeHelpFlag = true,
    bool defaultToLsp = false,
  }) {
    var parser = ArgParser(usageLineLength: usageLineLength);
    if (includeHelpFlag) {
      parser.addFlag(
        helpFlag,
        abbr: 'h',
        negatable: false,
        help: 'Print this usage information.',
      );
    }
    parser.addOption(
      clientIdOption,
      valueHelp: 'name',
      help: 'An identifier for the analysis server client.',
    );
    parser.addOption(
      clientVersionOption,
      valueHelp: 'version',
      help: 'The version of the analysis server client.',
    );
    parser.addOption(
      dartSdkOption,
      valueHelp: 'path',
      help: 'Override the Dart SDK to use for analysis.',
    );
    parser.addOption(dartSdkAliasOption, hide: true);
    parser.addOption(
      cacheFolderOption,
      valueHelp: 'path',
      help: 'Override the location of the analysis server\'s cache.',
    );
    parser.addOption(
      packagesFileOption,
      valueHelp: 'path',
      help:
          'The path to the package resolution configuration file, which '
          'supplies a mapping of package names\ninto paths.',
    );
    parser.addMultiOption(
      enableExperimentOption,
      valueHelp: 'experiment',
      help:
          'Enable one or more experimental features '
          '(see dart.dev/go/experiments).',
      hide: true,
    );

    parser.addOption(
      serverProtocolOption,
      defaultsTo: defaultToLsp ? protocolLsp : protocolAnalyzer,
      valueHelp: 'protocol',
      allowed: [protocolLsp, protocolAnalyzer],
      allowedHelp: {
        protocolLsp:
            'The Language Server Protocol '
            '(https://microsoft.github.io/language-server-protocol)',
        protocolAnalyzer:
            'Dart\'s analysis server protocol '
            '(https://dart.dev/go/analysis-server-protocol)',
      },
      help: 'Specify the protocol to use to communicate with the analysis server.',
    );
    // This option is hidden but still accepted; it's effectively translated to
    // the 'protocol' option above.
    parser.addFlag(
      useLspFlag,
      negatable: false,
      help: 'Whether to use the Language Server Protocol (LSP).',
      hide: true,
    );

    parser.addSeparator('Server diagnostics:');

    parser.addOption(
      protocolTrafficLogOption,
      valueHelp: 'file path',
      help: 'Write server protocol traffic to the given file.',
    );
    parser.addOption(protocolTrafficLogAliasOption, hide: true);

    parser.addOption(
      sessionLogOption,
      valueHelp: 'file path',
      help: 'Write a server session log to the given file.',
    );

    parser.addOption(
      performanceLogOption,
      valueHelp: 'file path',
      help: 'Write a server performance log to the given file.',
    );

    parser.addOption(
      analysisDriverLogOption,
      valueHelp: 'file path',
      help: 'Write analysis driver diagnostic data to the given file.',
    );
    parser.addOption(analysisDriverLogAliasOption, hide: true);

    parser.addOption(
      diagnosticPortOption,
      valueHelp: 'port',
      help:
          'Serve a web UI for status and performance data on the given '
          'port.',
    );
    parser.addOption(diagnosticPortAliasOption, hide: true);

    //
    // Hidden; these have not yet been made public.
    //
    parser.addFlag(
      analyticsFlag,
      help:
          'Allow or disallow sending analytics information to '
          'Google for this session.',
      hide: true,
    );
    parser.addFlag(
      suppressAnalyticsFlag,
      negatable: false,
      help: 'Suppress analytics for this session.',
      hide: true,
    );

    //
    // Hidden; these are for internal development.
    //
    parser.addOption(
      trainUsingOption,
      valueHelp: 'path',
      help:
          'Pass in a directory to analyze for purposes of training an '
          'analysis server snapshot.  Disables analytics.',
      hide: true,
    );
    parser.addFlag(
      disableFileByteStoreOption,
      help: 'Disable persistent byte storage. Intended for benchmarking.',
      hide: true,
    );
    parser.addFlag(
      useSingleFileByteStoreOption,
      help: 'Use the experimental single-file persistent byte store.',
      hide: true,
    );
    parser.addFlag(
      withFineDependenciesOption,
      help: 'Enable fine-grained dependencies.',
      defaultsTo: true,
      hide: true,
    );
    parser.addFlag(
      disableServerExceptionHandlingOption,
      // TODO(jcollins-g): Pipeline option through and apply to all
      // exception-nullifying runZoned() calls.
      help:
          'disable analyzer exception capture for interactive debugging '
          'of the server',
      hide: true,
    );
    parser.addFlag(
      disableServerFeatureCompletionOption,
      help: 'disable all completion features',
      hide: true,
    );
    parser.addFlag(
      disableServerFeatureSearchOption,
      help: 'disable all search features',
      hide: true,
    );
    parser.addFlag(
      pluginsFlag,
      help: 'Use analyzer plugins',
      defaultsTo: true,
      hide: true,
    );
    parser.addFlag(
      disableSilentAnalysisExceptionsOption,
      negatable: false,
      help: 'Prevent exceptions during analysis from being silent',
      hide: true,
    );
    parser.addFlag(
      disableStatusNotificationDebouncingOption,
      negatable: false,
      help: 'Suppress debouncing of status notifications.',
      hide: true,
    );
    parser.addFlag(
      internalPrintToConsoleOption,
      help: 'enable sending `print` output to the console',
      negatable: false,
      hide: true,
    );
    parser.addOption(
      reportProtocolVersionOption,
      valueHelp: 'version',
      help:
          'The protocol version that the server will report to the client, '
          'can be used to temporary enabling features that we expect to be '
          'available in future versions.',
      hide: true,
    );

    //
    // Hidden; these are deprecated and no longer read from.
    //

    // Removed 11/15/2020.
    parser.addOption('completion-model', hide: true);
    // Removed 11/8/2020.
    parser.addFlag('dartpad', hide: true);
    // Removed 11/15/2020.
    parser.addFlag('enable-completion-model', hide: true);
    // Removed 9/23/2020.
    parser.addFlag('enable-instrumentation', hide: true);
    // Removed 11/12/2020.
    parser.addOption('file-read-mode', hide: true);
    // Removed 11/12/2020.
    parser.addFlag('ignore-unrecognized-flags', hide: true);
    // Removed 11/8/2020.
    parser.addFlag('preview-dart-2', hide: true);
    // Removed 11/12/2020.
    parser.addFlag('useAnalysisHighlight2', hide: true);
    // Removed 11/13/2020.
    parser.addFlag('use-new-relevance', hide: true);
    // Removed 9/23/2020.
    parser.addFlag('use-fasta-parser', hide: true);

    return parser;
  }

  /// Perform log files rolling.
  ///
  /// Rename existing files with names `[path].(x)` to `[path].(x+1)`.
  /// Keep at most [numOld] files.
  /// Rename the file with the given [path] to `[path].1`.
  static void _rollLogFiles(String path, int numOld) {
    for (var i = numOld - 1; i >= 0; i--) {
      try {
        var oldPath = i == 0 ? path : '$path.$i';
        File(oldPath).renameSync('$path.${i + 1}');
      } catch (e) {
        // If a file can't be renamed, then leave it and attempt to rename the
        // remaining files.
      }
    }
  }
}

/// Implements the [DiagnosticServer] class by wrapping an [HttpAnalysisServer].
class _DiagnosticServerImpl extends DiagnosticServer {
  late HttpAnalysisServer httpServer;

  @override
  Future<int> getServerPort() async => (await httpServer.serveHttp())!;

  Future<void> startOnPort(int port) {
    return httpServer.serveHttp(port);
  }
}
