// 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/analysis_server.dart';
import 'package:analysis_server/src/analytics/analytics_manager.dart';
import 'package:analysis_server/src/analytics/noop_analytics_manager.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/socket_server.dart';
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:telemetry/telemetry.dart' as telemetry;

/// 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 BINARY_NAME = 'analysis_server';

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

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

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

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

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

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

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

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

  /// Suppress analytics for this session.
  static const String SUPPRESS_ANALYTICS_FLAG = 'suppress-analytics';

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

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

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

  /// 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 DIAGNOSTIC_PORT = 'diagnostic-port';
  static const String DIAGNOSTIC_PORT_ALIAS = 'port';

  /// The path to the SDK.
  static const String DART_SDK = 'dart-sdk';
  static const String DART_SDK_ALIAS = 'sdk';

  /// The path to the data cache.
  static const String CACHE_FOLDER = 'cache';

  /// The path to the package config file override.
  static const String PACKAGES_FILE = 'packages';

  /// The forced protocol version that the server will report to the client.
  static const String REPORT_PROTOCOL_VERSION = 'report-protocol-version';

  /// The name of the flag specifying the server protocol to use.
  static const String SERVER_PROTOCOL = 'protocol';
  static const String PROTOCOL_ANALYZER = 'analyzer';
  static const String PROTOCOL_LSP = 'lsp';

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

  /// A directory to analyze in order to train an analysis server snapshot.
  static const String TRAIN_USING = 'train-using';

  /// 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.
  InstrumentationService? instrumentationService;

  HttpAnalysisServer? httpServer;

  Driver();

  /// 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 [IsolateChannel].
  @override
  void start(
    List<String> arguments, {
    SendPort? sendPort,
    bool defaultToLsp = false,
  }) {
    var sessionStartTime = DateTime.now();
    var parser = createArgParser(defaultToLsp: defaultToLsp);
    var results = parser.parse(arguments);

    var analysisServerOptions = AnalysisServerOptions();
    analysisServerOptions.newAnalysisDriverLog =
        (results[ANALYSIS_DRIVER_LOG] ?? results[ANALYSIS_DRIVER_LOG_ALIAS])
            as String?;
    if (results.wasParsed(USE_LSP)) {
      analysisServerOptions.useLanguageServerProtocol =
          results[USE_LSP] as bool;
    } else {
      analysisServerOptions.useLanguageServerProtocol =
          results[SERVER_PROTOCOL] == PROTOCOL_LSP;
    }
    // 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[CLIENT_ID] as String?) ??
        (analysisServerOptions.useLanguageServerProtocol
            ? 'unknown.client.lsp'
            : 'unknown.client.classic');
    analysisServerOptions.clientId = clientId;
    analysisServerOptions.clientVersion = results[CLIENT_VERSION] as String?;
    analysisServerOptions.cacheFolder = results[CACHE_FOLDER] as String?;
    analysisServerOptions.packagesFile = results[PACKAGES_FILE] as String?;
    analysisServerOptions.reportProtocolVersion =
        results[REPORT_PROTOCOL_VERSION] as String?;

    analysisServerOptions.enabledExperiments =
        results.wasParsed(ENABLE_EXPERIMENT)
            ? results[ENABLE_EXPERIMENT] as List<String>
            : <String>[];

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

    // Analytics
    var disableAnalyticsForSession = results[SUPPRESS_ANALYTICS_FLAG] as bool;
    if (results.wasParsed(TRAIN_USING)) {
      disableAnalyticsForSession = true;
    }

    // Use sdkConfig to optionally override analytics settings.
    final analyticsId = sdkConfig.analyticsId ?? 'UA-26406144-29';
    final forceAnalyticsEnabled = sdkConfig.analyticsForceEnabled == true;
    var analytics = telemetry.createAnalyticsInstance(
      analyticsId,
      'analysis-server',
      disableForSession: disableAnalyticsForSession,
      forceEnabled: forceAnalyticsEnabled,
    );
    analysisServerOptions.analytics = analytics;

    // Record the client name as the application installer ID.
    analytics.setSessionValue('aiid', analysisServerOptions.clientId);
    if (analysisServerOptions.clientVersion != null) {
      analytics.setSessionValue('cd1', analysisServerOptions.clientVersion);
    }
    var analyticsManager = NoopAnalyticsManager();

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

      // TODO(devoncarew): Replace with a real enablement check.
      return false;
    }

    // Crash reporting

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

    if (telemetry.showAnalyticsUI) {
      if (results.wasParsed(ANALYTICS_FLAG)) {
        analytics.enabled = results[ANALYTICS_FLAG] as bool;
        print(telemetry.createAnalyticsStatusMessage(analytics.enabled));
        return;
      }
    }

    {
      var disableCompletion =
          results[DISABLE_SERVER_FEATURE_COMPLETION] as bool;
      var disableSearch = results[DISABLE_SERVER_FEATURE_SEARCH] as bool;
      if (disableCompletion || disableSearch) {
        analysisServerOptions.featureSet = FeatureSet(
          completion: !disableCompletion,
          search: !disableSearch,
        );
      }
    }

    if (results[HELP_OPTION] as bool) {
      _printUsage(parser, analytics, fromHelp: true);
      return;
    }

    final defaultSdkPath = _getSdkPath(results);
    final 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);
    //
    // Record the start of the session.
    //
    analyticsManager.startUp(
        time: sessionStartTime,
        arguments: _getArgumentsForAnalytics(results),
        clientId: clientId,
        clientVersion: analysisServerOptions.clientVersion,
        sdkVersion: defaultSdk.sdkVersion);
    //
    // Initialize the instrumentation service.
    //
    var logFilePath = (results[PROTOCOL_TRAFFIC_LOG] ??
        results[PROTOCOL_TRAFFIC_LOG_ALIAS]) as String?;
    var allInstrumentationServices = this.instrumentationService == null
        ? <InstrumentationService>[]
        : [this.instrumentationService!];
    if (logFilePath != null) {
      _rollLogFiles(logFilePath, 5);
      allInstrumentationServices.add(
          InstrumentationLogAdapter(FileInstrumentationLogger(logFilePath)));
    }

    var errorNotifier = ErrorNotifier();
    allInstrumentationServices
        .add(CrashReportingInstrumentation(crashReportSender));
    final instrumentationService =
        MulticastInstrumentationService(allInstrumentationServices);
    this.instrumentationService = instrumentationService;

    instrumentationService.logVersion(
      results[TRAIN_USING] != null
          ? 'training-0'
          : _readUuid(instrumentationService),
      analysisServerOptions.clientId ?? '',
      analysisServerOptions.clientVersion ?? '',
      PROTOCOL_VERSION,
      defaultSdk.languageVersion.toString(),
    );
    AnalysisEngine.instance.instrumentationService = instrumentationService;

    int? diagnosticServerPort;
    final portValue =
        (results[DIAGNOSTIC_PORT] ?? results[DIAGNOSTIC_PORT_ALIAS]) as String?;
    if (portValue != null) {
      try {
        diagnosticServerPort = int.parse(portValue);
      } on FormatException {
        print('Invalid port number: $portValue');
        print('');
        _printUsage(parser, analytics);
        exitCode = 1;
        return;
      }
    }

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

  void startAnalysisServer(
    ArgResults results,
    AnalysisServerOptions analysisServerOptions,
    ArgParser parser,
    DartSdkManager dartSdkManager,
    AnalyticsManager analyticsManager,
    CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
    InstrumentationService instrumentationService,
    RequestStatisticsHelper requestStatistics,
    telemetry.Analytics analytics,
    int? diagnosticServerPort,
    ErrorNotifier errorNotifier,
    SendPort? sendPort,
  ) {
    var capture = results[DISABLE_SERVER_EXCEPTION_HANDLING] as bool
        ? (_, Function f, {Function(String)? print}) => f()
        : _captureExceptions;
    var trainDirectory = results[TRAIN_USING] as String?;
    if (trainDirectory != null) {
      if (!FileSystemEntity.isDirectorySync(trainDirectory)) {
        print("Training directory '$trainDirectory' not found.\n");
        exitCode = 1;
        return;
      }
    }
    //
    // Register lint rules.
    //
    linter.registerLintRules();

    var diagnosticServer = _DiagnosticServerImpl();

    // Ping analytics with our initial call.
    analytics.sendScreenView('home');

    //
    // Create the sockets and start listening for requests.
    //
    final socketServer = SocketServer(
        analysisServerOptions,
        dartSdkManager,
        crashReportingAttachmentsBuilder,
        instrumentationService,
        requestStatistics,
        diagnosticServer,
        analyticsManager,
        detachableFileSystemManager);
    httpServer = HttpAnalysisServer(socketServer);

    errorNotifier.server = socketServer.analysisServer;

    diagnosticServer.httpServer = httpServer!;
    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;

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

        final httpServer = this.httpServer;
        if (httpServer != null) {
          httpServer.close();
        }
        await instrumentationService.shutdown();

        socketServer.analysisServer!.shutdown();

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

        exit(exitCode);
      }();
    } else {
      capture(instrumentationService, () {
        Future serveResult;
        if (sendPort == null) {
          var stdioServer = StdioAnalysisServer(socketServer);
          serveResult = stdioServer.serveStdio();
        } else {
          var isolateAnalysisServer = IsolateAnalysisServer(socketServer);
          serveResult = isolateAnalysisServer.serveIsolate(sendPort);
        }
        serveResult.then((_) async {
          final httpServer = this.httpServer;
          if (httpServer != null) {
            httpServer.close();
          }
          await instrumentationService.shutdown();
          socketServer.analysisServer!.shutdown();
          if (sendPort == null) exit(0);
        });
      },
          print: results[INTERNAL_PRINT_TO_CONSOLE] as bool
              ? null
              : httpServer!.recordPrint);
    }
  }

  void startLspServer(
    ArgResults args,
    AnalysisServerOptions analysisServerOptions,
    DartSdkManager dartSdkManager,
    AnalyticsManager analyticsManager,
    InstrumentationService instrumentationService,
    int? diagnosticServerPort,
    ErrorNotifier errorNotifier,
  ) {
    var capture = args[DISABLE_SERVER_EXCEPTION_HANDLING] as bool
        ? (_, Function f, {Function(String)? print}) => f()
        : _captureExceptions;

    linter.registerLintRules();

    var diagnosticServer = _DiagnosticServerImpl();

    final socketServer = LspSocketServer(
      analysisServerOptions,
      diagnosticServer,
      analyticsManager,
      dartSdkManager,
      instrumentationService,
    );
    errorNotifier.server = socketServer.analysisServer;

    diagnosticServer.httpServer = httpServer = HttpAnalysisServer(socketServer);

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

    capture(instrumentationService, () {
      var stdioServer = LspStdioAnalysisServer(socketServer);
      stdioServer.serveStdio().then((_) async {
        // Only shutdown the server and exit if the server is not already
        // handling the shutdown.
        if (!socketServer.analysisServer!.willExit) {
          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, void Function() callback,
      {void Function(String line)? print}) {
    void errorFunction(Zone self, ZoneDelegate parent, Zone zone,
        Object exception, StackTrace stackTrace) {
      service.logException(exception, 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);
  }

  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 = [
      ANALYTICS_FLAG,
      CACHE_FOLDER,
      CLIENT_ID,
      CLIENT_VERSION,
      'completion-model',
      'dartpad',
      DART_SDK,
      DART_SDK_ALIAS,
      DIAGNOSTIC_PORT,
      DIAGNOSTIC_PORT_ALIAS,
      DISABLE_SERVER_EXCEPTION_HANDLING,
      DISABLE_SERVER_FEATURE_COMPLETION,
      DISABLE_SERVER_FEATURE_SEARCH,
      'enable-completion-model',
      'enable-experiment',
      'enable-instrumentation',
      'file-read-mode',
      HELP_OPTION,
      'ignore-unrecognized-flags',
      INTERNAL_PRINT_TO_CONSOLE,
      PACKAGES_FILE,
      'preview-dart-2',
      PROTOCOL_TRAFFIC_LOG,
      PROTOCOL_TRAFFIC_LOG_ALIAS,
      REPORT_PROTOCOL_VERSION,
      SERVER_PROTOCOL,
      SUPPRESS_ANALYTICS_FLAG,
      TRAIN_USING,
      'useAnalysisHighlight2',
      USE_LSP,
      'use-new-relevance',
      'use-fasta-parser',
    ];
    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(DART_SDK);
    tryCandidateArgument(DART_SDK_ALIAS);
    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,
    telemetry.Analytics analytics, {
    bool fromHelp = false,
  }) {
    print('Usage: $BINARY_NAME [flags]');
    print('');
    print('Supported flags are:');
    print(parser.usage);

    if (telemetry.showAnalyticsUI) {
      // Print analytics status and information.
      if (fromHelp) {
        print('');
        print(telemetry.analyticsNotice);
      }
      print('');
      print(telemetry.createAnalyticsStatusMessage(analytics.enabled,
          command: ANALYTICS_FLAG));
    }
  }

  /// Read the UUID from disk, generating and storing a new one if necessary.
  String _readUuid(InstrumentationService service) {
    final 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);
    }
    var uuid = _generateUuidString();
    try {
      uuidFile.parent.createSync(recursive: true);
      uuidFile.writeAsStringSync(uuid);
    } catch (exception, stackTrace) {
      service.logException(exception, 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(HELP_OPTION,
          abbr: 'h', negatable: false, help: 'Print this usage information.');
    }
    parser.addOption(CLIENT_ID,
        valueHelp: 'name',
        help: 'An identifier for the analysis server client.');
    parser.addOption(CLIENT_VERSION,
        valueHelp: 'version',
        help: 'The version of the analysis server client.');
    parser.addOption(DART_SDK,
        valueHelp: 'path', help: 'Override the Dart SDK to use for analysis.');
    parser.addOption(DART_SDK_ALIAS, hide: true);
    parser.addOption(CACHE_FOLDER,
        valueHelp: 'path',
        help: 'Override the location of the analysis server\'s cache.');
    parser.addOption(
      PACKAGES_FILE,
      valueHelp: 'path',
      help: 'The path to the package resolution configuration file, which '
          'supplies a mapping of package names\ninto paths.',
    );
    parser.addMultiOption(
      ENABLE_EXPERIMENT,
      valueHelp: 'experiment',
      help: 'Enable one or more experimental features '
          '(see dart.dev/go/experiments).',
      hide: true,
    );

    parser.addOption(
      SERVER_PROTOCOL,
      defaultsTo: defaultToLsp ? PROTOCOL_LSP : PROTOCOL_ANALYZER,
      valueHelp: 'protocol',
      allowed: [PROTOCOL_LSP, PROTOCOL_ANALYZER],
      allowedHelp: {
        PROTOCOL_LSP: 'The Language Server Protocol '
            '(https://microsoft.github.io/language-server-protocol)',
        PROTOCOL_ANALYZER: '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(USE_LSP,
        defaultsTo: false,
        negatable: false,
        help: 'Whether to use the Language Server Protocol (LSP).',
        hide: true);

    parser.addSeparator('Server diagnostics:');

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

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

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

    //
    // Hidden; these have not yet been made public.
    //
    parser.addFlag(ANALYTICS_FLAG,
        help: 'enable or disable sending analytics information to Google',
        hide: !telemetry.showAnalyticsUI);
    parser.addFlag(SUPPRESS_ANALYTICS_FLAG,
        negatable: false,
        help: 'suppress analytics for this session',
        hide: !telemetry.showAnalyticsUI);

    //
    // Hidden; these are for internal development.
    //
    parser.addOption(TRAIN_USING,
        valueHelp: 'path',
        help: 'Pass in a directory to analyze for purposes of training an '
            'analysis server snapshot.',
        hide: true);
    parser.addFlag(DISABLE_SERVER_EXCEPTION_HANDLING,
        // 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',
        defaultsTo: false,
        hide: true);
    parser.addFlag(DISABLE_SERVER_FEATURE_COMPLETION,
        help: 'disable all completion features', defaultsTo: false, hide: true);
    parser.addFlag(DISABLE_SERVER_FEATURE_SEARCH,
        help: 'disable all search features', defaultsTo: false, hide: true);
    parser.addFlag(INTERNAL_PRINT_TO_CONSOLE,
        help: 'enable sending `print` output to the console',
        defaultsTo: false,
        negatable: false,
        hide: true);
    parser.addOption(
      REPORT_PROTOCOL_VERSION,
      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;

  _DiagnosticServerImpl();

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

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