// 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' as io;
import 'dart:math' show max;

import 'package:analysis_server/lsp_protocol/protocol.dart' as lsp;
import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart'
    hide AnalysisOptions, MessageType;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/analytics/analytics_manager.dart';
import 'package:analysis_server/src/channel/channel.dart';
import 'package:analysis_server/src/computer/computer_highlights.dart';
import 'package:analysis_server/src/domains/analysis/occurrences.dart';
import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
import 'package:analysis_server/src/flutter/flutter_notifications.dart';
import 'package:analysis_server/src/handler/legacy/analysis_get_errors.dart';
import 'package:analysis_server/src/handler/legacy/analysis_get_hover.dart';
import 'package:analysis_server/src/handler/legacy/analysis_get_imported_elements.dart';
import 'package:analysis_server/src/handler/legacy/analysis_get_navigation.dart';
import 'package:analysis_server/src/handler/legacy/analysis_get_signature.dart';
import 'package:analysis_server/src/handler/legacy/analysis_reanalyze.dart';
import 'package:analysis_server/src/handler/legacy/analysis_set_analysis_roots.dart';
import 'package:analysis_server/src/handler/legacy/analysis_set_general_subscriptions.dart';
import 'package:analysis_server/src/handler/legacy/analysis_set_priority_files.dart';
import 'package:analysis_server/src/handler/legacy/analysis_set_subscriptions.dart';
import 'package:analysis_server/src/handler/legacy/analysis_update_content.dart';
import 'package:analysis_server/src/handler/legacy/analysis_update_options.dart';
import 'package:analysis_server/src/handler/legacy/analytics_enable.dart';
import 'package:analysis_server/src/handler/legacy/analytics_is_enabled.dart';
import 'package:analysis_server/src/handler/legacy/analytics_send_event.dart';
import 'package:analysis_server/src/handler/legacy/analytics_send_timing.dart';
import 'package:analysis_server/src/handler/legacy/completion_get_suggestion_details2.dart';
import 'package:analysis_server/src/handler/legacy/completion_get_suggestions2.dart';
import 'package:analysis_server/src/handler/legacy/diagnostic_get_diagnostics.dart';
import 'package:analysis_server/src/handler/legacy/diagnostic_get_server_port.dart';
import 'package:analysis_server/src/handler/legacy/edit_bulk_fixes.dart';
import 'package:analysis_server/src/handler/legacy/edit_format.dart';
import 'package:analysis_server/src/handler/legacy/edit_format_if_enabled.dart';
import 'package:analysis_server/src/handler/legacy/edit_get_assists.dart';
import 'package:analysis_server/src/handler/legacy/edit_get_available_refactorings.dart';
import 'package:analysis_server/src/handler/legacy/edit_get_fixes.dart';
import 'package:analysis_server/src/handler/legacy/edit_get_postfix_completion.dart';
import 'package:analysis_server/src/handler/legacy/edit_get_refactoring.dart';
import 'package:analysis_server/src/handler/legacy/edit_get_statement_completion.dart';
import 'package:analysis_server/src/handler/legacy/edit_import_elements.dart';
import 'package:analysis_server/src/handler/legacy/edit_is_postfix_completion_applicable.dart';
import 'package:analysis_server/src/handler/legacy/edit_list_postfix_completion_templates.dart';
import 'package:analysis_server/src/handler/legacy/edit_organize_directives.dart';
import 'package:analysis_server/src/handler/legacy/edit_sort_members.dart';
import 'package:analysis_server/src/handler/legacy/execution_create_context.dart';
import 'package:analysis_server/src/handler/legacy/execution_delete_context.dart';
import 'package:analysis_server/src/handler/legacy/execution_get_suggestions.dart';
import 'package:analysis_server/src/handler/legacy/execution_map_uri.dart';
import 'package:analysis_server/src/handler/legacy/execution_set_subscriptions.dart';
import 'package:analysis_server/src/handler/legacy/flutter_get_widget_description.dart';
import 'package:analysis_server/src/handler/legacy/flutter_set_subscriptions.dart';
import 'package:analysis_server/src/handler/legacy/flutter_set_widget_property_value.dart';
import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
import 'package:analysis_server/src/handler/legacy/lsp_over_legacy_handler.dart';
import 'package:analysis_server/src/handler/legacy/search_find_element_references.dart';
import 'package:analysis_server/src/handler/legacy/search_find_member_declarations.dart';
import 'package:analysis_server/src/handler/legacy/search_find_member_references.dart';
import 'package:analysis_server/src/handler/legacy/search_find_top_level_declarations.dart';
import 'package:analysis_server/src/handler/legacy/search_get_element_declarations.dart';
import 'package:analysis_server/src/handler/legacy/search_get_type_hierarchy.dart';
import 'package:analysis_server/src/handler/legacy/server_cancel_request.dart';
import 'package:analysis_server/src/handler/legacy/server_get_version.dart';
import 'package:analysis_server/src/handler/legacy/server_set_client_capabilities.dart';
import 'package:analysis_server/src/handler/legacy/server_set_subscriptions.dart';
import 'package:analysis_server/src/handler/legacy/server_shutdown.dart';
import 'package:analysis_server/src/handler/legacy/unsupported_request.dart';
import 'package:analysis_server/src/lsp/client_capabilities.dart' as lsp;
import 'package:analysis_server/src/lsp/client_configuration.dart' as lsp;
import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
import 'package:analysis_server/src/operation/operation_analysis.dart';
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/protocol_server.dart' as server;
import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/server/debounce_requests.dart';
import 'package:analysis_server/src/server/detachable_filesystem_manager.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/performance.dart';
import 'package:analysis_server/src/server/sdk_configuration.dart';
import 'package:analysis_server/src/services/completion/completion_state.dart';
import 'package:analysis_server/src/services/execution/execution_context.dart';
import 'package:analysis_server/src/services/flutter/widget_descriptions.dart';
import 'package:analysis_server/src/services/refactoring/legacy/refactoring_manager.dart';
import 'package:analysis_server/src/services/user_prompts/dart_fix_prompt_manager.dart';
import 'package:analysis_server/src/utilities/process.dart';
import 'package:analysis_server/src/utilities/request_statistics.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/dart/analysis/status.dart' as analysis;
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/utilities/cancellation.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
import 'package:analyzer_plugin/src/utilities/client_uri_converter.dart';
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:telemetry/crash_reporting.dart';
import 'package:watcher/watcher.dart';

/// A function that can be executed to create a handler for a request.
typedef HandlerGenerator = LegacyHandler Function(
    LegacyAnalysisServer, Request, CancellationToken, OperationPerformanceImpl);

typedef OptionUpdater = void Function(AnalysisOptionsImpl options);

/// Various IDE options.
class AnalysisServerOptions {
  String? newAnalysisDriverLog;

  String? clientId;
  String? clientVersion;

  /// Base path where to cache data.
  String? cacheFolder;

  /// The path to the package config file override.
  /// If `null`, then the default discovery mechanism is used.
  String? packagesFile;

  /// The crash report sender instance; note, this object can be `null`, and
  /// should be accessed via a null-aware operator.
  CrashReportSender? crashReportSender;

  /// An optional set of configuration overrides specified by the SDK.
  ///
  /// These overrides can provide new values for configuration settings, and are
  /// generally used in specific SDKs (like the internal google3 one).
  SdkConfiguration? configurationOverrides;

  /// Whether to use the Language Server Protocol.
  bool useLanguageServerProtocol = false;

  /// The set of enabled features.
  FeatureSet featureSet = FeatureSet();

  /// If set, this string will be reported as the protocol version.
  String? reportProtocolVersion;

  /// Experiments which have been enabled (or disabled) via the
  /// `--enable-experiment` command-line option.
  List<String> enabledExperiments = [];
}

/// Instances of the class [LegacyAnalysisServer] implement a server that
/// listens on a [CommunicationChannel] for analysis requests and processes
/// them.
class LegacyAnalysisServer extends AnalysisServer {
  /// A map from the name of a request to a function used to create a request
  /// handler.
  ///
  /// Requests that don't match anything in this map will be passed to
  /// [LspOverLegacyHandler] for possible handling before returning an error.
  static final Map<String, HandlerGenerator> requestHandlerGenerators = {
    ANALYSIS_REQUEST_GET_ERRORS: AnalysisGetErrorsHandler.new,
    ANALYSIS_REQUEST_GET_HOVER: AnalysisGetHoverHandler.new,
    ANALYSIS_REQUEST_GET_IMPORTED_ELEMENTS:
        AnalysisGetImportedElementsHandler.new,
    ANALYSIS_REQUEST_GET_LIBRARY_DEPENDENCIES: UnsupportedRequestHandler.new,
    ANALYSIS_REQUEST_GET_NAVIGATION: AnalysisGetNavigationHandler.new,
    ANALYSIS_REQUEST_GET_REACHABLE_SOURCES: UnsupportedRequestHandler.new,
    ANALYSIS_REQUEST_GET_SIGNATURE: AnalysisGetSignatureHandler.new,
    ANALYSIS_REQUEST_REANALYZE: AnalysisReanalyzeHandler.new,
    ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS: AnalysisSetAnalysisRootsHandler.new,
    ANALYSIS_REQUEST_SET_GENERAL_SUBSCRIPTIONS:
        AnalysisSetGeneralSubscriptionsHandler.new,
    ANALYSIS_REQUEST_SET_PRIORITY_FILES: AnalysisSetPriorityFilesHandler.new,
    ANALYSIS_REQUEST_SET_SUBSCRIPTIONS: AnalysisSetSubscriptionsHandler.new,
    ANALYSIS_REQUEST_UPDATE_CONTENT: AnalysisUpdateContentHandler.new,
    ANALYSIS_REQUEST_UPDATE_OPTIONS: AnalysisUpdateOptionsHandler.new,
    //
    ANALYTICS_REQUEST_IS_ENABLED: AnalyticsIsEnabledHandler.new,
    ANALYTICS_REQUEST_ENABLE: AnalyticsEnableHandler.new,
    ANALYTICS_REQUEST_SEND_EVENT: AnalyticsSendEventHandler.new,
    ANALYTICS_REQUEST_SEND_TIMING: AnalyticsSendTimingHandler.new,
    //
    COMPLETION_REQUEST_GET_SUGGESTION_DETAILS2:
        CompletionGetSuggestionDetails2Handler.new,
    COMPLETION_REQUEST_GET_SUGGESTIONS2: CompletionGetSuggestions2Handler.new,
    //
    DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS: DiagnosticGetDiagnosticsHandler.new,
    DIAGNOSTIC_REQUEST_GET_SERVER_PORT: DiagnosticGetServerPortHandler.new,
    //
    EDIT_REQUEST_FORMAT: EditFormatHandler.new,
    EDIT_REQUEST_FORMAT_IF_ENABLED: EditFormatIfEnabledHandler.new,
    EDIT_REQUEST_GET_ASSISTS: EditGetAssistsHandler.new,
    EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS:
        EditGetAvailableRefactoringsHandler.new,
    EDIT_REQUEST_BULK_FIXES: EditBulkFixes.new,
    EDIT_REQUEST_GET_FIXES: EditGetFixesHandler.new,
    EDIT_REQUEST_GET_REFACTORING: EditGetRefactoringHandler.new,
    EDIT_REQUEST_IMPORT_ELEMENTS: EditImportElementsHandler.new,
    EDIT_REQUEST_ORGANIZE_DIRECTIVES: EditOrganizeDirectivesHandler.new,
    EDIT_REQUEST_SORT_MEMBERS: EditSortMembersHandler.new,
    EDIT_REQUEST_GET_STATEMENT_COMPLETION:
        EditGetStatementCompletionHandler.new,
    EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE:
        EditIsPostfixCompletionApplicableHandler.new,
    EDIT_REQUEST_GET_POSTFIX_COMPLETION: EditGetPostfixCompletionHandler.new,
    EDIT_REQUEST_LIST_POSTFIX_COMPLETION_TEMPLATES:
        EditListPostfixCompletionTemplatesHandler.new,
    //
    EXECUTION_REQUEST_CREATE_CONTEXT: ExecutionCreateContextHandler.new,
    EXECUTION_REQUEST_DELETE_CONTEXT: ExecutionDeleteContextHandler.new,
    EXECUTION_REQUEST_GET_SUGGESTIONS: ExecutionGetSuggestionsHandler.new,
    EXECUTION_REQUEST_MAP_URI: ExecutionMapUriHandler.new,
    EXECUTION_REQUEST_SET_SUBSCRIPTIONS: ExecutionSetSubscriptionsHandler.new,
    //
    FLUTTER_REQUEST_GET_WIDGET_DESCRIPTION:
        FlutterGetWidgetDescriptionHandler.new,
    FLUTTER_REQUEST_SET_WIDGET_PROPERTY_VALUE:
        FlutterSetWidgetPropertyValueHandler.new,
    FLUTTER_REQUEST_SET_SUBSCRIPTIONS: FlutterSetSubscriptionsHandler.new,
    //
    SEARCH_REQUEST_FIND_ELEMENT_REFERENCES:
        SearchFindElementReferencesHandler.new,
    SEARCH_REQUEST_FIND_MEMBER_DECLARATIONS:
        SearchFindMemberDeclarationsHandler.new,
    SEARCH_REQUEST_FIND_MEMBER_REFERENCES:
        SearchFindMemberReferencesHandler.new,
    SEARCH_REQUEST_FIND_TOP_LEVEL_DECLARATIONS:
        SearchFindTopLevelDeclarationsHandler.new,
    SEARCH_REQUEST_GET_ELEMENT_DECLARATIONS:
        SearchGetElementDeclarationsHandler.new,
    SEARCH_REQUEST_GET_TYPE_HIERARCHY: SearchGetTypeHierarchyHandler.new,
    //
    SERVER_REQUEST_CANCEL_REQUEST: ServerCancelRequestHandler.new,
    SERVER_REQUEST_GET_VERSION: ServerGetVersionHandler.new,
    SERVER_REQUEST_SET_CLIENT_CAPABILITIES:
        ServerSetClientCapabilitiesHandler.new,
    SERVER_REQUEST_SET_SUBSCRIPTIONS: ServerSetSubscriptionsHandler.new,
    SERVER_REQUEST_SHUTDOWN: ServerShutdownHandler.new,

    //
    LSP_REQUEST_HANDLE: LspOverLegacyHandler.new,
  };

  /// The channel from which requests are received and to which responses should
  /// be sent.
  final ServerCommunicationChannel channel;

  @override
  late final FutureOr<InitializedStateMessageHandler> lspInitialized =
      InitializedStateMessageHandler(this);

  /// A flag indicating the value of the 'analyzing' parameter sent in the last
  /// status message to the client.
  bool statusAnalyzing = false;

  /// A set of the [ServerService]s to send notifications for.
  Set<ServerService> serverServices = {};

  /// A table mapping request ids to cancellation tokens that allow cancelling
  /// the request.
  ///
  /// Tokens are removed once a request completes and should not be assumed to
  /// exist in this table just because cancellation was requested.
  Map<String, CancelableToken> cancellationTokens = {};

  /// A set of the [GeneralAnalysisService]s to send notifications for.
  Set<GeneralAnalysisService> generalAnalysisServices = {};

  /// A table mapping [AnalysisService]s to the file paths for which these
  /// notifications should be sent.
  Map<AnalysisService, Set<String>> analysisServices = {};

  /// The most recently registered set of client capabilities. The default is to
  /// have no registered requests and no additional capabilities.
  ///
  /// Must be modified through the [clientCapabilities] setter.
  ServerSetClientCapabilitiesParams _clientCapabilities =
      ServerSetClientCapabilitiesParams([]);

  @override
  final lspClientCapabilities = lsp.LspClientCapabilities(
    lsp.ClientCapabilities(
      textDocument: lsp.TextDocumentClientCapabilities(
        hover: lsp.HoverClientCapabilities(
          contentFormat: [
            lsp.MarkupKind.Markdown,
          ],
        ),
      ),
      workspace: lsp.WorkspaceClientCapabilities(
        workspaceEdit: lsp.WorkspaceEditClientCapabilities(
          documentChanges: true,
        ),
      ),
    ),
  );

  @override
  final lsp.LspClientConfiguration lspClientConfiguration;

  /// A table mapping [FlutterService]s to the file paths for which these
  /// notifications should be sent.
  Map<FlutterService, Set<String>> flutterServices = {};

  /// The support for Flutter properties.
  WidgetDescriptions flutterWidgetDescriptions = WidgetDescriptions();

  /// The state used by the completion domain handlers.
  final CompletionState completionState = CompletionState();

  /// The object used to manage uncompleted refactorings.
  late RefactoringManager? _refactoringManager;

  /// The context used by the execution domain handlers.
  final ExecutionContext executionContext = ExecutionContext();

  /// The next search response id.
  int nextSearchId = 0;

  /// The [Completer] that completes when analysis is complete.
  Completer<void>? _onAnalysisCompleteCompleter;

  /// The controller that is notified when analysis is started.
  final StreamController<bool> _onAnalysisStartedController =
      StreamController.broadcast();

  /// If the "analysis.analyzedFiles" notification is currently being subscribed
  /// to (see [generalAnalysisServices]), and at least one such notification has
  /// been sent since the subscription was enabled, the set of analyzed files
  /// that was delivered in the most recently sent notification.  Otherwise
  /// `null`.
  Set<String>? prevAnalyzedFiles;

  /// The controller for [onAnalysisSetChanged].
  final StreamController<void> _onAnalysisSetChangedController =
      StreamController.broadcast(sync: true);

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

  /// The broadcast stream of requests that were discarded because there
  /// was another request that made this one irrelevant.
  @visibleForTesting
  final StreamController<Request> discardedRequests =
      StreamController.broadcast(sync: true);

  /// The index of the next request from the server to the client.
  int nextServerRequestId = 0;

  /// A table mapping the ids of requests sent from the server to the client
  /// that have not yet received a response, to the completer used to return the
  /// response when it has been received.
  Map<String, Completer<Response>> pendingServerRequests = {};

  /// Whether the server should send LSP notifications.
  ///
  /// This is set once the client sends any LSP request or client capability
  /// that depends on LSP functionality.
  bool sendLspNotifications = false;

  /// Initialize a newly created server to receive requests from and send
  /// responses to the given [channel].
  ///
  /// If [rethrowExceptions] is true, then any exceptions thrown by analysis are
  /// propagated up the call stack.  The default is true to allow analysis
  /// exceptions to show up in unit tests, but it should be set to false when
  /// running a full analysis server.
  LegacyAnalysisServer(
    this.channel,
    ResourceProvider baseResourceProvider,
    AnalysisServerOptions options,
    DartSdkManager sdkManager,
    AnalyticsManager analyticsManager,
    CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
    InstrumentationService instrumentationService, {
    http.Client? httpClient,
    ProcessRunner? processRunner,
    RequestStatisticsHelper? requestStatistics,
    DiagnosticServer? diagnosticServer,
    this.detachableFileSystemManager,
    // Disable to avoid using this in unit tests.
    bool enableBlazeWatcher = false,
    DartFixPromptManager? dartFixPromptManager,
    super.providedByteStore,
    super.pluginManager,
  })  : lspClientConfiguration =
            lsp.LspClientConfiguration(baseResourceProvider.pathContext),
        super(
          options,
          sdkManager,
          diagnosticServer,
          analyticsManager,
          crashReportingAttachmentsBuilder,
          baseResourceProvider,
          instrumentationService,
          httpClient,
          processRunner,
          NotificationManager(channel, baseResourceProvider.pathContext),
          requestStatistics: requestStatistics,
          enableBlazeWatcher: enableBlazeWatcher,
          dartFixPromptManager: dartFixPromptManager,
        ) {
    var contextManagerCallbacks =
        ServerContextManagerCallbacks(this, resourceProvider);
    contextManager.callbacks = contextManagerCallbacks;

    analysisDriverSchedulerEventsSubscription =
        analysisDriverScheduler.events.listen(handleAnalysisEvent);
    analysisDriverScheduler.start();

    onAnalysisStarted.first.then((_) {
      onAnalysisComplete.then((_) {
        performance = performanceAfterStartup = ServerPerformance();
      });
    });
    channel.sendNotification(
      ServerConnectedParams(
        options.reportProtocolVersion ?? PROTOCOL_VERSION,
        io.pid,
      ).toNotification(clientUriConverter: uriConverter),
    );
    debounceRequests(channel, discardedRequests)
        .listen(handleRequestOrResponse, onDone: done, onError: error);
    _newRefactoringManager();
  }

  /// The most recently registered set of client capabilities. The default is to
  /// have no registered requests and no additional capabilities.
  ServerSetClientCapabilitiesParams get clientCapabilities =>
      _clientCapabilities;

  /// Updates the current set of client capabilities.
  set clientCapabilities(ServerSetClientCapabilitiesParams capabilities) {
    _clientCapabilities = capabilities;

    if (capabilities.supportsUris ?? false) {
      // URI support implies LSP, as that's the only way to access (and get
      // change notifications for) custom-scheme files.
      uriConverter = ClientUriConverter.withVirtualFileSupport(
          resourceProvider.pathContext);
      initializeLspOverLegacy();
    } else {
      uriConverter = ClientUriConverter.noop(resourceProvider.pathContext);
    }
  }

  /// The [Future] that completes when analysis is complete.
  Future<void> get onAnalysisComplete {
    if (isAnalysisComplete()) {
      return Future.value();
    }
    var completer = _onAnalysisCompleteCompleter ??= Completer<void>();
    return completer.future;
  }

  /// The stream that is notified when the analysis set is changed - this might
  /// be a change to a file, external via a watch event, or internal via
  /// overlay. This means that the resolved world might have changed.
  ///
  /// The type of produced elements is not specified and should not be used.
  Stream<void> get onAnalysisSetChanged =>
      _onAnalysisSetChangedController.stream;

  /// The stream that is notified with `true` when analysis is started.
  Stream<bool> get onAnalysisStarted {
    return _onAnalysisStartedController.stream;
  }

  @override
  OpenUriNotificationSender? get openUriNotificationSender {
    if (!clientCapabilities.requests.contains('openUrlRequest')) {
      return null;
    }

    return (Uri uri) async {
      var requestId = '${nextServerRequestId++}';
      await sendRequest(
        ServerOpenUrlRequestParams('$uri')
            .toRequest(requestId, clientUriConverter: uriConverter),
      );
    };
  }

  RefactoringManager? get refactoringManager {
    var refactoringManager = _refactoringManager;
    if (refactoringManager == null) {
      return null;
    }
    if (refactoringManager.hasPendingRequest) {
      refactoringManager.cancel();
      _newRefactoringManager();
    }
    return _refactoringManager;
  }

  String get sdkPath {
    return sdkManager.defaultSdkDirectory;
  }

  @override
  @protected
  bool get supportsShowMessageRequest =>
      clientCapabilities.requests.contains('showMessageRequest');

  void cancelRequest(String id) {
    cancellationTokens[id]?.cancel();
  }

  /// The socket from which requests are being read has been closed.
  void done() {}

  /// There was an error related to the socket from which requests are being
  /// read.
  void error(argument) {}

  /// Return the cached analysis result for the file with the given [path].
  /// If there is no cached result, return `null`.
  ResolvedUnitResult? getCachedResolvedUnit(String path) {
    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
      return null;
    }

    var driver = getAnalysisDriver(path);
    return driver?.getCachedResolvedUnit(path);
  }

  /// Gets the current version number of a document.
  ///
  /// For the legacy server we do not track version numbers, these are
  /// LSP-specific.
  @override
  int? getDocumentVersion(String path) => null;

  @override
  FutureOr<void> handleAnalysisStatusChange(analysis.AnalysisStatus status) {
    super.handleAnalysisStatusChange(status);
    sendStatusNotificationNew(status);
  }

  /// Handle a [request] that was read from the communication channel.
  void handleRequest(Request request) {
    var startTime = DateTime.now();
    performance.logRequestTiming(request.clientRequestTime);

    // Because we don't `await` the execution of the handlers, we wrap the
    // execution in order to have one central place to handle exceptions.
    runZonedGuarded(() async {
      // Record performance information for the request.
      var rootPerformance = OperationPerformanceImpl('<root>');
      RequestPerformance? requestPerformance;
      await rootPerformance.runAsync('request', (performance) async {
        requestPerformance = RequestPerformance(
          operation: request.method,
          performance: performance,
          requestLatency: request.timeSinceRequest,
          startTime: startTime,
        );
        recentPerformance.requests.add(requestPerformance!);

        var cancellationToken = CancelableToken();
        cancellationTokens[request.id] = cancellationToken;
        var generator = requestHandlerGenerators[request.method];
        if (generator != null) {
          var handler =
              generator(this, request, cancellationToken, performance);
          if (!handler.recordsOwnAnalytics) {
            analyticsManager.startedRequest(
                request: request, startTime: startTime);
          }
          await handler.handle();
        } else {
          analyticsManager.startedRequest(
              request: request, startTime: startTime);
          sendResponse(Response.unknownRequest(request));
        }
      });
      if (requestPerformance != null &&
          requestPerformance!.performance.elapsed >
              ServerRecentPerformance.slowRequestsThreshold) {
        recentPerformance.slowRequests.add(requestPerformance!);
      }
    }, (exception, stackTrace) {
      if (exception is InconsistentAnalysisException) {
        sendResponse(Response.contentModified(request));
      } else if (exception is RequestFailure) {
        sendResponse(exception.response);
      } else {
        // Log the exception.
        instrumentationService.logException(
          FatalException(
            'Failed to handle request: ${request.method}',
            exception,
            stackTrace,
          ),
          null,
          crashReportingAttachmentsBuilder.forException(exception),
        );
        // Then return an error response to the client.
        var error =
            RequestError(RequestErrorCode.SERVER_ERROR, exception.toString());
        error.stackTrace = stackTrace.toString();
        var response = Response(request.id, error: error);
        sendResponse(response);
      }
    });
  }

  /// Handle a [request] that was read from the communication channel.
  void handleRequestOrResponse(RequestOrResponse requestOrResponse) {
    if (requestOrResponse is Request) {
      handleRequest(requestOrResponse);
    } else if (requestOrResponse is Response) {
      handleResponse(requestOrResponse);
    }
  }

  /// Handle a [response] that was read from the communication channel.
  void handleResponse(Response response) {
    var completer = pendingServerRequests.remove(response.id);
    if (completer != null) {
      completer.complete(response);
    }
  }

  /// Initializes LSP support over the legacy server.
  ///
  /// This method is called when the client sends an LSP request, or indicates
  /// that it will use LSP-overy-Legacy via client capabilities.
  ///
  /// This only applies to LSP over the legacy protocol and not DTD, since we
  /// do not want a DTD-LSP client to trigger LSP notifications going to the
  /// legacy protocol client, only the legacy protocol client should do that.
  void initializeLspOverLegacy() {
    sendLspNotifications = true;
  }

  /// Return `true` if the [path] is both absolute and normalized.
  bool isAbsoluteAndNormalized(String path) {
    var pathContext = resourceProvider.pathContext;
    return pathContext.isAbsolute(path) && pathContext.normalize(path) == path;
  }

  /// Return `true` if analysis is complete.
  bool isAnalysisComplete() {
    return !analysisDriverScheduler.isWorking;
  }

  /// Return `true` if the given path is a valid `FilePath`.
  ///
  /// This means that it is absolute and normalized.
  bool isValidFilePath(String path) {
    return resourceProvider.pathContext.isAbsolute(path) &&
        resourceProvider.pathContext.normalize(path) == path;
  }

  @override
  void notifyFlutterWidgetDescriptions(String path) {
    flutterWidgetDescriptions.flush();
  }

  /// Send the given LSP [notification] to the client.
  @override
  void sendLspNotification(lsp.NotificationMessage notification) {
    if (!sendLspNotifications) {
      return;
    }

    channel.sendNotification(
      LspNotificationParams(notification)
          .toNotification(clientUriConverter: uriConverter),
    );
  }

  /// Send the given [notification] to the client.
  void sendNotification(Notification notification) {
    channel.sendNotification(notification);
  }

  /// Send the given [request] to the client.
  Future<Response> sendRequest(Request request) {
    var completer = Completer<Response>();
    pendingServerRequests[request.id] = completer;
    channel.sendRequest(request);
    return completer.future;
  }

  /// Send the given [response] to the client.
  void sendResponse(Response response) {
    channel.sendResponse(response);
    analyticsManager.sentResponse(response: response);
    cancellationTokens.remove(response.id);
  }

  /// If the [path] is not a valid file path, that is absolute and normalized,
  /// send an error response, and return `true`. If OK then return `false`.
  bool sendResponseErrorIfInvalidFilePath(Request request, String path) {
    if (!isAbsoluteAndNormalized(path)) {
      sendResponse(Response.invalidFilePathFormat(request, path));
      return true;
    }
    return false;
  }

  /// Sends a `server.error` notification.
  @override
  void sendServerErrorNotification(
    String message,
    dynamic exception,
    /*StackTrace*/ stackTrace, {
    bool fatal = false,
  }) {
    var msg = exception == null ? message : '$message: $exception';
    if (stackTrace != null && exception is! CaughtException) {
      stackTrace = StackTrace.current;
    }

    // send the notification
    channel.sendNotification(ServerErrorParams(fatal, msg, '$stackTrace')
        .toNotification(clientUriConverter: uriConverter));

    // remember the last few exceptions
    if (exception is CaughtException) {
      stackTrace ??= exception.stackTrace;
    }

    exceptions.add(ServerException(
      message,
      exception,
      stackTrace is StackTrace ? stackTrace : StackTrace.current,
      fatal,
    ));
  }

  /// Send status notification to the client. The state of analysis is given by
  /// the [status] information.
  void sendStatusNotificationNew(analysis.AnalysisStatus status) {
    var isAnalyzing = status.isWorking;
    if (isAnalyzing) {
      _onAnalysisStartedController.add(true);
    }
    var onAnalysisCompleteCompleter = _onAnalysisCompleteCompleter;
    if (onAnalysisCompleteCompleter != null && !isAnalyzing) {
      onAnalysisCompleteCompleter.complete();
      _onAnalysisCompleteCompleter = null;
    }
    // Perform on-idle actions.
    if (!isAnalyzing) {
      if (generalAnalysisServices
          .contains(GeneralAnalysisService.ANALYZED_FILES)) {
        sendAnalysisNotificationAnalyzedFiles(this);
      }
      _scheduleAnalysisImplementedNotification();
      filesResolvedSinceLastIdle.clear();
    }
    // Only send status when subscribed.
    if (!serverServices.contains(ServerService.STATUS)) {
      return;
    }
    // Only send status when it changes
    if (statusAnalyzing == isAnalyzing) {
      return;
    }
    statusAnalyzing = isAnalyzing;
    if (!isAnalyzing) {
      // Only send analysis analytics after analysis is complete.
      reportAnalysisAnalytics();
    }
    var analysis = AnalysisStatus(isAnalyzing);
    channel.sendNotification(ServerStatusParams(analysis: analysis)
        .toNotification(clientUriConverter: uriConverter));
  }

  /// Implementation for `analysis.setAnalysisRoots`.
  ///
  // TODO(scheglov): implement complete projects/contexts semantics.
  //
  // The current implementation is intentionally simplified and expected
  // that only folders are given each given folder corresponds to the exactly
  // one context.
  //
  // So, we can start working in parallel on adding services and improving
  // projects/contexts support.
  Future<void> setAnalysisRoots(String requestId, List<String> includedPaths,
      List<String> excludedPaths) async {
    var completer = analysisContextRebuildCompleter = Completer();
    try {
      notificationManager.setAnalysisRoots(includedPaths, excludedPaths);
      try {
        await contextManager.setRoots(includedPaths, excludedPaths);
      } on UnimplementedError catch (e) {
        throw RequestFailure(Response.unsupportedFeature(
            requestId, e.message ?? 'Unsupported feature.'));
      }
    } finally {
      completer.complete();
    }
  }

  /// Implementation for `analysis.setSubscriptions`.
  void setAnalysisSubscriptions(
      Map<AnalysisService, Set<String>> subscriptions) {
    notificationManager.setSubscriptions(subscriptions);
    analysisServices = subscriptions;
    _sendSubscriptions(analysis: true);
  }

  /// Implementation for `flutter.setSubscriptions`.
  void setFlutterSubscriptions(Map<FlutterService, Set<String>> subscriptions) {
    flutterServices = subscriptions;
    _sendSubscriptions(flutter: true);
  }

  /// Implementation for `analysis.setGeneralSubscriptions`.
  void setGeneralAnalysisSubscriptions(
      List<GeneralAnalysisService> subscriptions) {
    var newServices = subscriptions.toSet();
    if (newServices.contains(GeneralAnalysisService.ANALYZED_FILES) &&
        !generalAnalysisServices
            .contains(GeneralAnalysisService.ANALYZED_FILES) &&
        isAnalysisComplete()) {
      sendAnalysisNotificationAnalyzedFiles(this);
    } else if (!newServices.contains(GeneralAnalysisService.ANALYZED_FILES) &&
        generalAnalysisServices
            .contains(GeneralAnalysisService.ANALYZED_FILES)) {
      prevAnalyzedFiles = null;
    }
    generalAnalysisServices = newServices;
  }

  /// Set the priority files to the given [files].
  void setPriorityFiles(String requestId, List<String> files) {
    bool isPubspec(String filePath) =>
        file_paths.isPubspecYaml(resourceProvider.pathContext, filePath);

    // When pubspecs are opened, trigger pre-loading of pub package names and
    // versions.
    var pubspecs = files.where(isPubspec).toList();
    if (pubspecs.isNotEmpty) {
      pubPackageService.beginCachePreloads(pubspecs);
    }

    priorityFiles.clear();
    priorityFiles.addAll(files);
    // Set priority files in drivers.
    for (var driver in driverMap.values) {
      driver.priorityFiles = files;
    }
  }

  @override
  @visibleForOverriding
  Future<String?> showUserPrompt(
    MessageType type,
    String message,
    List<String> actionLabels,
  ) async {
    assert(supportsShowMessageRequest);
    var requestId = (nextServerRequestId++).toString();
    var actions = actionLabels.map((label) => MessageAction(label)).toList();
    var request =
        ServerShowMessageRequestParams(type.forLegacy, message, actions)
            .toRequest(requestId, clientUriConverter: uriConverter);
    var response = await sendRequest(request);
    return response.result?['action'] as String?;
  }

  @override
  Future<void> shutdown() async {
    await super.shutdown();

    pubApi.close();

    detachableFileSystemManager?.dispose();

    // Defer closing the channel and shutting down the instrumentation server so
    // that the shutdown response can be sent and logged.
    unawaited(Future(() {
      instrumentationService.shutdown();
      channel.close();
    }));
  }

  /// Implementation for `analysis.updateContent`.
  void updateContent(String id, Map<String, dynamic> changes) {
    _onAnalysisSetChangedController.add(null);
    changes.forEach((file, change) {
      // Prepare the old overlay contents.
      String? oldContents;
      try {
        if (resourceProvider.hasOverlay(file)) {
          oldContents = resourceProvider.getFile(file).readAsStringSync();
        }
      } catch (_) {}

      // Prepare the new contents.
      String? newContents;
      if (change is AddContentOverlay) {
        newContents = change.content;
      } else if (change is ChangeContentOverlay) {
        if (oldContents == null) {
          // The client may only send a ChangeContentOverlay if there is
          // already an existing overlay for the source.
          throw RequestFailure(Response(id,
              error: RequestError(RequestErrorCode.INVALID_OVERLAY_CHANGE,
                  'Invalid overlay change')));
        }
        try {
          newContents = SourceEdit.applySequence(oldContents, change.edits);
        } on RangeError {
          throw RequestFailure(Response(id,
              error: RequestError(RequestErrorCode.INVALID_OVERLAY_CHANGE,
                  'Invalid overlay change')));
        }
      } else if (change is RemoveContentOverlay) {
        newContents = null;
      } else {
        // Protocol parsing should have ensured that we never get here.
        throw AnalysisException('Illegal change type');
      }

      if (newContents != null) {
        resourceProvider.setOverlay(
          file,
          content: newContents,
          modificationStamp: overlayModificationStamp++,
        );
      } else {
        resourceProvider.removeOverlay(file);
      }

      for (var driver in driverMap.values) {
        driver.changeFile(file);
      }

      // If the file did not exist, and is "overlay only", it still should be
      // analyzed. Add it to driver to which it should have been added.
      contextManager.getDriverFor(file)?.addFile(file);

      notifyDeclarationsTracker(file);
      notifyFlutterWidgetDescriptions(file);

      // TODO(scheglov): implement other cases
    });
  }

  /// Use the given updaters to update the values of the options in every
  /// existing analysis context.
  void updateOptions(List<OptionUpdater> optionUpdaters) {
    // TODO(scheglov): implement for the new analysis driver
//    //
//    // Update existing contexts.
//    //
//    for (AnalysisContext context in analysisContexts) {
//      AnalysisOptionsImpl options =
//          new AnalysisOptionsImpl.from(context.analysisOptions);
//      optionUpdaters.forEach((OptionUpdater optionUpdater) {
//        optionUpdater(options);
//      });
//      context.analysisOptions = options;
//      // `TODO`(brianwilkerson) As far as I can tell, this doesn't cause analysis
//      // to be scheduled for this context.
//    }
//    //
//    // Update the defaults used to create new contexts.
//    //
//    optionUpdaters.forEach((OptionUpdater optionUpdater) {
//      optionUpdater(defaultContextOptions);
//    });
  }

  /// Returns `true` if there is a subscription for the given [service] and
  /// [file].
  bool _hasAnalysisServiceSubscription(AnalysisService service, String file) {
    return analysisServices[service]?.contains(file) ?? false;
  }

  bool _hasFlutterServiceSubscription(FlutterService service, String file) {
    return flutterServices[service]?.contains(file) ?? false;
  }

  /// Initializes [_refactoringManager] with a new instance.
  void _newRefactoringManager() {
    _refactoringManager = RefactoringManager(this, refactoringWorkspace);
  }

  void _scheduleAnalysisImplementedNotification() {
    var subscribed = analysisServices[AnalysisService.IMPLEMENTED];
    if (subscribed == null) {
      return;
    }

    var toSend = subscribed.intersection(filesResolvedSinceLastIdle);
    if (toSend.isEmpty) {
      return;
    }

    scheduleImplementedNotification(this, toSend);
  }

  void _sendSubscriptions({bool analysis = false, bool flutter = false}) {
    var files = <String>{};

    if (analysis) {
      for (var serviceFiles in analysisServices.values) {
        files.addAll(serviceFiles);
      }
    }

    if (flutter) {
      for (var serviceFiles in flutterServices.values) {
        files.addAll(serviceFiles);
      }
    }

    for (var file in files) {
      // The result will be produced by the "results" stream with
      // the fully resolved unit, and processed with sending analysis
      // notifications as it happens after content changes.
      if (file_paths.isDart(resourceProvider.pathContext, file)) {
        getResolvedUnit(file, sendCachedToStream: true);
      }
    }
  }
}

class ServerContextManagerCallbacks
    extends CommonServerContextManagerCallbacks {
  @override
  final LegacyAnalysisServer analysisServer;

  ServerContextManagerCallbacks(this.analysisServer, super.resourceProvider);

  AbstractNotificationManager get _notificationManager =>
      analysisServer.notificationManager;

  @override
  void afterContextsCreated() {
    super.afterContextsCreated();
    analysisServer._sendSubscriptions(analysis: true, flutter: true);
  }

  @override
  void afterWatchEvent(WatchEvent event) {
    analysisServer._onAnalysisSetChangedController.add(null);
  }

  @override
  void flushResults(List<String> files) {
    sendAnalysisNotificationFlushResults(analysisServer, files);
  }

  @override
  void handleResolvedUnitResult(ResolvedUnitResult result) {
    var path = result.path;

    var unit = result.unit;
    if (analysisServer._hasAnalysisServiceSubscription(
        AnalysisService.HIGHLIGHTS, path)) {
      _runDelayed(() {
        _notificationManager.recordHighlightRegions(
            NotificationManager.serverId, path, _computeHighlightRegions(unit));
      });
    }
    if (analysisServer._hasAnalysisServiceSubscription(
        AnalysisService.NAVIGATION, path)) {
      _runDelayed(() {
        _notificationManager.recordNavigationParams(
            NotificationManager.serverId,
            path,
            _computeNavigationParams(path, result));
      });
    }
    if (analysisServer._hasAnalysisServiceSubscription(
        AnalysisService.OCCURRENCES, path)) {
      _runDelayed(() {
        _notificationManager.recordOccurrences(
            NotificationManager.serverId, path, _computeOccurrences(unit));
      });
    }
    // if (analysisServer._hasAnalysisServiceSubscription(
    //     AnalysisService.OUTLINE, path)) {
    //   _runDelayed(() {
    //     // `TODO`(brianwilkerson) Change NotificationManager to store params
    //     // so that fileKind and libraryName can be recorded / passed along.
    //     notificationManager.recordOutlines(NotificationManager.serverId, path,
    //         _computeOutlineParams(path, unit, result.lineInfo));
    //   });
    // }
    if (analysisServer._hasAnalysisServiceSubscription(
        AnalysisService.CLOSING_LABELS, path)) {
      _runDelayed(() {
        sendAnalysisNotificationClosingLabels(
            analysisServer, path, result.lineInfo, unit);
      });
    }
    if (analysisServer._hasAnalysisServiceSubscription(
        AnalysisService.FOLDING, path)) {
      _runDelayed(() {
        sendAnalysisNotificationFolding(
            analysisServer, path, result.lineInfo, unit);
      });
    }
    if (analysisServer._hasAnalysisServiceSubscription(
        AnalysisService.OUTLINE, path)) {
      _runDelayed(() {
        sendAnalysisNotificationOutline(analysisServer, result);
      });
    }
    if (analysisServer._hasAnalysisServiceSubscription(
        AnalysisService.OVERRIDES, path)) {
      _runDelayed(() {
        sendAnalysisNotificationOverrides(analysisServer, path, unit);
      });
    }
    if (analysisServer._hasFlutterServiceSubscription(
        FlutterService.OUTLINE, path)) {
      _runDelayed(() {
        sendFlutterNotificationOutline(analysisServer, result);
      });
    }
  }

  List<HighlightRegion> _computeHighlightRegions(CompilationUnit unit) {
    return DartUnitHighlightsComputer(unit).compute();
  }

  server.AnalysisNavigationParams _computeNavigationParams(
      String path, ParsedUnitResult result) {
    var collector = NavigationCollectorImpl();
    computeDartNavigation(resourceProvider, collector, result, null, null);
    collector.createRegions();
    return server.AnalysisNavigationParams(
        path, collector.regions, collector.targets, collector.files);
  }

  List<Occurrences> _computeOccurrences(CompilationUnit unit) {
    var collector = OccurrencesCollectorImpl();
    addDartOccurrences(collector, unit);
    return collector.allOccurrences;
  }

  /// Run [f] in a new [Future].
  ///
  /// This method is used to delay sending notifications. If there is a more
  /// important consumer of an analysis results, specifically a code completion
  /// computer, we want it to run before spending time of sending notifications.
  ///
  // TODO(scheglov): Consider replacing this with full priority based scheduler.
  //
  // TODO(scheglov): Alternatively, if code completion work in a way that does
  // not produce (at first) fully resolved unit, but only part of it - a single
  // method, or a top-level declaration, we would not have this problem - the
  // completion computer would be the only consumer of the partial analysis
  // result.
  void _runDelayed(Function() f) {
    Future(f);
  }
}

/// Used to record server exceptions.
class ServerException {
  final String message;
  final dynamic exception;
  final StackTrace stackTrace;
  final bool fatal;

  ServerException(this.message, this.exception, this.stackTrace, this.fatal);

  @override
  String toString() => message;
}

/// A class used by [LegacyAnalysisServer] to record performance information
/// such as request latency.
class ServerPerformance {
  /// The creation time and the time when performance information
  /// started to be recorded here.
  final int startTime = DateTime.now().millisecondsSinceEpoch;

  /// The number of requests.
  int requestCount = 0;

  /// The number of requests that recorded latency information.
  int latencyCount = 0;

  /// The total latency (milliseconds) for all recorded requests.
  int requestLatency = 0;

  /// The maximum latency (milliseconds) for all recorded requests.
  int maxLatency = 0;

  /// The number of requests with latency > 150 milliseconds.
  int slowRequestCount = 0;

  /// Log timing information for a request.
  void logRequestTiming(int? clientRequestTime) {
    ++requestCount;
    if (clientRequestTime != null) {
      var latency = DateTime.now().millisecondsSinceEpoch - clientRequestTime;
      ++latencyCount;
      requestLatency += latency;
      maxLatency = max(maxLatency, latency);
      if (latency > 150) {
        ++slowRequestCount;
      }
    }
  }
}
