// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/lsp/client_capabilities.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/semantic_tokens/legend.dart';

/// Helper for reading client dynamic registrations which may be ommitted by the
/// client.
class ClientDynamicRegistrations {
  /// All dynamic registrations supported by the Dart LSP server.
  ///
  /// Anything listed here and supported by the client will not send a static
  /// registration but instead dynamically register (usually only for a subset of
  /// files such as for .dart/pubspec.yaml/etc).
  ///
  /// When adding new capabilities that will be registered dynamically, the
  /// test_dynamicRegistration_XXX tests in `lsp/initialization_test.dart` should
  /// also be updated to ensure no double-registrations.
  static const supported = [
    Method.textDocument_didOpen,
    Method.textDocument_didChange,
    Method.textDocument_didClose,
    Method.textDocument_completion,
    Method.textDocument_hover,
    Method.textDocument_signatureHelp,
    Method.textDocument_references,
    Method.textDocument_documentHighlight,
    Method.textDocument_documentColor,
    Method.textDocument_formatting,
    Method.textDocument_onTypeFormatting,
    Method.textDocument_rangeFormatting,
    Method.textDocument_definition,
    Method.textDocument_codeAction,
    Method.textDocument_rename,
    Method.textDocument_foldingRange,
    Method.textDocument_selectionRange,
    Method.textDocument_typeDefinition,
    // workspace.fileOperations covers all file operation methods but we only
    // support this one.
    Method.workspace_willRenameFiles,
    // Sematic tokens are all registered under a single "method" as the
    // actual methods are controlled by the server capabilities.
    CustomMethods.semanticTokenDynamicRegistration,
  ];
  final ClientCapabilities _capabilities;

  ClientDynamicRegistrations(this._capabilities);

  bool get codeActions =>
      _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;

  bool get colorProvider =>
      _capabilities.textDocument?.colorProvider?.dynamicRegistration ?? false;

  bool get completion =>
      _capabilities.textDocument?.completion?.dynamicRegistration ?? false;

  bool get definition =>
      _capabilities.textDocument?.definition?.dynamicRegistration ?? false;

  bool get didChangeConfiguration =>
      _capabilities.workspace?.didChangeConfiguration?.dynamicRegistration ??
      false;

  bool get documentHighlights =>
      _capabilities.textDocument?.documentHighlight?.dynamicRegistration ??
      false;

  bool get documentSymbol =>
      _capabilities.textDocument?.documentSymbol?.dynamicRegistration ?? false;

  bool get fileOperations =>
      _capabilities.workspace?.fileOperations?.dynamicRegistration ?? false;

  bool get folding =>
      _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;

  bool get formatting =>
      _capabilities.textDocument?.formatting?.dynamicRegistration ?? false;

  bool get hover =>
      _capabilities.textDocument?.hover?.dynamicRegistration ?? false;

  bool get implementation =>
      _capabilities.textDocument?.implementation?.dynamicRegistration ?? false;

  bool get rangeFormatting =>
      _capabilities.textDocument?.rangeFormatting?.dynamicRegistration ?? false;

  bool get references =>
      _capabilities.textDocument?.references?.dynamicRegistration ?? false;

  bool get rename =>
      _capabilities.textDocument?.rename?.dynamicRegistration ?? false;

  bool get selectionRange =>
      _capabilities.textDocument?.selectionRange?.dynamicRegistration ?? false;

  bool get semanticTokens =>
      _capabilities.textDocument?.semanticTokens?.dynamicRegistration ?? false;

  bool get signatureHelp =>
      _capabilities.textDocument?.signatureHelp?.dynamicRegistration ?? false;

  bool get textSync =>
      _capabilities.textDocument?.synchronization?.dynamicRegistration ?? false;

  bool get typeDefinition =>
      _capabilities.textDocument?.typeDefinition?.dynamicRegistration ?? false;

  bool get typeFormatting =>
      _capabilities.textDocument?.onTypeFormatting?.dynamicRegistration ??
      false;
}

class ServerCapabilitiesComputer {
  static final fileOperationRegistrationOptions =
      FileOperationRegistrationOptions(
    filters: [
      FileOperationFilter(
        scheme: 'file',
        pattern: FileOperationPattern(
          glob: '**/*.dart',
          matches: FileOperationPatternKind.file,
        ),
      )
    ],
  );

  final LspAnalysisServer _server;

  /// List of current registrations.
  Set<Registration> currentRegistrations = {};
  var _lastRegistrationId = 0;

  final dartFiles = TextDocumentFilter(language: 'dart', scheme: 'file');
  final pubspecFile = TextDocumentFilter(
      language: 'yaml', scheme: 'file', pattern: '**/pubspec.yaml');
  final analysisOptionsFile = TextDocumentFilter(
      language: 'yaml', scheme: 'file', pattern: '**/analysis_options.yaml');
  final fixDataFile = TextDocumentFilter(
      language: 'yaml', scheme: 'file', pattern: '**/lib/fix_data.yaml');

  ServerCapabilitiesComputer(this._server);
  ServerCapabilities computeServerCapabilities(
      LspClientCapabilities clientCapabilities) {
    final codeActionLiteralSupport = clientCapabilities.literalCodeActions;
    final renameOptionsSupport = clientCapabilities.renameValidation;
    final enableFormatter =
        _server.clientConfiguration.global.enableSdkFormatter;
    final previewCommitCharacters =
        _server.clientConfiguration.global.previewCommitCharacters;

    final dynamicRegistrations =
        ClientDynamicRegistrations(clientCapabilities.raw);

    // When adding new capabilities to the server that may apply to specific file
    // types, it's important to update
    // [IntializedMessageHandler._performDynamicRegistration()] to notify
    // supporting clients of this. This avoids clients needing to hard-code the
    // list of what files types we support (and allows them to avoid sending
    // requests where we have only partial support for some types).
    return ServerCapabilities(
      textDocumentSync: dynamicRegistrations.textSync
          ? null
          : Either2<TextDocumentSyncKind, TextDocumentSyncOptions>.t2(
              TextDocumentSyncOptions(
              // The open/close and sync kind flags are registered dynamically if the
              // client supports them, so these static registrations are based on whether
              // the client supports dynamic registration.
              openClose: true,
              change: TextDocumentSyncKind.Incremental,
              willSave: false,
              willSaveWaitUntil: false,
              save: null,
            )),
      completionProvider: dynamicRegistrations.completion
          ? null
          : CompletionOptions(
              triggerCharacters: dartCompletionTriggerCharacters,
              allCommitCharacters: previewCommitCharacters
                  ? dartCompletionCommitCharacters
                  : null,
              resolveProvider: true,
            ),
      hoverProvider: dynamicRegistrations.hover
          ? null
          : Either2<bool, HoverOptions>.t1(true),
      signatureHelpProvider: dynamicRegistrations.signatureHelp
          ? null
          : SignatureHelpOptions(
              triggerCharacters: dartSignatureHelpTriggerCharacters,
              retriggerCharacters: dartSignatureHelpRetriggerCharacters,
            ),
      definitionProvider: dynamicRegistrations.definition
          ? null
          : Either2<bool, DefinitionOptions>.t1(true),
      implementationProvider: dynamicRegistrations.implementation
          ? null
          : Either3<bool, ImplementationOptions,
              ImplementationRegistrationOptions>.t1(
              true,
            ),
      referencesProvider: dynamicRegistrations.references
          ? null
          : Either2<bool, ReferenceOptions>.t1(true),
      documentHighlightProvider: dynamicRegistrations.documentHighlights
          ? null
          : Either2<bool, DocumentHighlightOptions>.t1(true),
      documentSymbolProvider: dynamicRegistrations.documentSymbol
          ? null
          : Either2<bool, DocumentSymbolOptions>.t1(true),
      // "The `CodeActionOptions` return type is only valid if the client
      // signals code action literal support via the property
      // `textDocument.codeAction.codeActionLiteralSupport`."
      codeActionProvider: dynamicRegistrations.codeActions
          ? null
          : codeActionLiteralSupport
              ? Either2<bool, CodeActionOptions>.t2(CodeActionOptions(
                  codeActionKinds: DartCodeActionKind.serverSupportedKinds,
                ))
              : Either2<bool, CodeActionOptions>.t1(true),
      colorProvider: dynamicRegistrations.colorProvider
          ? null
          : Either3<bool, DocumentColorOptions,
                  DocumentColorRegistrationOptions>.t3(
              DocumentColorRegistrationOptions(documentSelector: [dartFiles])),
      documentFormattingProvider: dynamicRegistrations.formatting
          ? null
          : Either2<bool, DocumentFormattingOptions>.t1(enableFormatter),
      documentOnTypeFormattingProvider: dynamicRegistrations.typeFormatting
          ? null
          : enableFormatter
              ? DocumentOnTypeFormattingOptions(
                  firstTriggerCharacter: dartTypeFormattingCharacters.first,
                  moreTriggerCharacter:
                      dartTypeFormattingCharacters.skip(1).toList())
              : null,
      documentRangeFormattingProvider: dynamicRegistrations.typeFormatting
          ? null
          : Either2<bool, DocumentRangeFormattingOptions>.t1(enableFormatter),
      renameProvider: dynamicRegistrations.rename
          ? null
          : renameOptionsSupport
              ? Either2<bool, RenameOptions>.t2(
                  RenameOptions(prepareProvider: true))
              : Either2<bool, RenameOptions>.t1(true),
      foldingRangeProvider: dynamicRegistrations.folding
          ? null
          : Either3<bool, FoldingRangeOptions,
              FoldingRangeRegistrationOptions>.t1(
              true,
            ),
      selectionRangeProvider: dynamicRegistrations.selectionRange
          ? null
          : Either3<bool, SelectionRangeOptions,
              SelectionRangeRegistrationOptions>.t1(true),
      semanticTokensProvider: dynamicRegistrations.semanticTokens
          ? null
          : Either2<SemanticTokensOptions,
              SemanticTokensRegistrationOptions>.t1(
              SemanticTokensOptions(
                legend: semanticTokenLegend.lspLegend,
                full: Either2<bool, SemanticTokensOptionsFull>.t2(
                  SemanticTokensOptionsFull(delta: false),
                ),
                range: Either2<bool, SemanticTokensOptionsRange>.t1(true),
              ),
            ),
      executeCommandProvider: ExecuteCommandOptions(
        commands: Commands.serverSupportedCommands,
        workDoneProgress: true,
      ),
      workspaceSymbolProvider: Either2<bool, WorkspaceSymbolOptions>.t1(true),
      workspace: ServerCapabilitiesWorkspace(
        workspaceFolders: WorkspaceFoldersServerCapabilities(
          supported: true,
          changeNotifications: Either2<bool, String>.t1(true),
        ),
        fileOperations: dynamicRegistrations.fileOperations
            ? null
            : FileOperationOptions(
                willRename: fileOperationRegistrationOptions,
              ),
      ),
    );
  }

  /// If the client supports dynamic registrations we can tell it what methods
  /// we support for which documents. For example, this allows us to ask for
  /// file edits for .dart as well as pubspec.yaml but only get hover/completion
  /// calls for .dart. This functionality may not be supported by the client, in
  /// which case they will use the ServerCapabilities to know which methods we
  /// support and it will be up to them to decide which file types they will
  /// send requests for.
  Future<void> performDynamicRegistration() async {
    final pluginTypes = _server.pluginManager.plugins
        .expand((plugin) => plugin.currentSession?.interestingFiles ?? const [])
        // All published plugins use something like `*.extension` as
        // interestingFiles. Prefix a `**/` so that the glob matches nested
        // folders as well.
        .map((glob) => TextDocumentFilter(scheme: 'file', pattern: '**/$glob'));
    final pluginTypesExcludingDart =
        pluginTypes.where((filter) => filter.pattern != '**/*.dart');

    final fullySupportedTypes = {dartFiles, ...pluginTypes}.toList();

    // Add pubspec + analysis options only for synchronisation. We do not support
    // things like hovers/formatting/etc. for these files so there's no point
    // in having the client send those requests (plus, for things like formatting
    // this could result in the editor reporting "multiple formatters installed"
    // and prevent a built-in YAML formatter from being selected).
    final synchronisedTypes = {
      ...fullySupportedTypes,
      pubspecFile,
      analysisOptionsFile,
      fixDataFile,
    }.toList();

    // Completion is supported for some synchronised files that we don't _fully_
    // support (eg. YAML). If these gain support for things like hover, we may
    // wish to move them to fullySupprtedTypes but add an exclusion for formatting.
    final completionSupportedTypesExcludingDart = {
      // Dart is excluded here at it's registered separately with trigger/commit
      // characters.
      ...pluginTypesExcludingDart,
      pubspecFile,
      analysisOptionsFile,
      fixDataFile,
    }.toList();

    final registrations = <Registration>[];

    final enableFormatter =
        _server.clientConfiguration.global.enableSdkFormatter;
    final previewCommitCharacters =
        _server.clientConfiguration.global.previewCommitCharacters;

    /// Helper for creating registrations with IDs.
    void register(bool condition, Method method, [ToJsonable? options]) {
      if (condition == true) {
        registrations.add(Registration(
            id: (_lastRegistrationId++).toString(),
            method: method.toString(),
            registerOptions: options));
      }
    }

    final dynamicRegistrations =
        ClientDynamicRegistrations(_server.clientCapabilities!.raw);

    register(
      dynamicRegistrations.textSync,
      Method.textDocument_didOpen,
      TextDocumentRegistrationOptions(documentSelector: synchronisedTypes),
    );
    register(
      dynamicRegistrations.textSync,
      Method.textDocument_didClose,
      TextDocumentRegistrationOptions(documentSelector: synchronisedTypes),
    );
    register(
      dynamicRegistrations.textSync,
      Method.textDocument_didChange,
      TextDocumentChangeRegistrationOptions(
          syncKind: TextDocumentSyncKind.Incremental,
          documentSelector: synchronisedTypes),
    );
    // Trigger and commit characters are specific to Dart, so register them
    // separately to the others.
    register(
      dynamicRegistrations.completion,
      Method.textDocument_completion,
      CompletionRegistrationOptions(
        documentSelector: [dartFiles],
        triggerCharacters: dartCompletionTriggerCharacters,
        allCommitCharacters:
            previewCommitCharacters ? dartCompletionCommitCharacters : null,
        resolveProvider: true,
      ),
    );
    register(
      dynamicRegistrations.completion,
      Method.textDocument_completion,
      CompletionRegistrationOptions(
        documentSelector: completionSupportedTypesExcludingDart,
        resolveProvider: true,
      ),
    );
    register(
      dynamicRegistrations.hover,
      Method.textDocument_hover,
      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
    );
    register(
      dynamicRegistrations.signatureHelp,
      Method.textDocument_signatureHelp,
      SignatureHelpRegistrationOptions(
        documentSelector: fullySupportedTypes,
        triggerCharacters: dartSignatureHelpTriggerCharacters,
        retriggerCharacters: dartSignatureHelpRetriggerCharacters,
      ),
    );
    register(
      dynamicRegistrations.references,
      Method.textDocument_references,
      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
    );
    register(
      dynamicRegistrations.documentHighlights,
      Method.textDocument_documentHighlight,
      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
    );
    register(
      dynamicRegistrations.documentSymbol,
      Method.textDocument_documentSymbol,
      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
    );
    register(
      dynamicRegistrations.colorProvider,
      // This registration covers both documentColor and colorPresentation.
      Method.textDocument_documentColor,
      DocumentColorRegistrationOptions(documentSelector: [dartFiles]),
    );
    register(
      enableFormatter && dynamicRegistrations.formatting,
      Method.textDocument_formatting,
      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
    );
    register(
      enableFormatter && dynamicRegistrations.typeFormatting,
      Method.textDocument_onTypeFormatting,
      DocumentOnTypeFormattingRegistrationOptions(
        documentSelector: [dartFiles], // This one is currently Dart-specific
        firstTriggerCharacter: dartTypeFormattingCharacters.first,
        moreTriggerCharacter: dartTypeFormattingCharacters.skip(1).toList(),
      ),
    );
    register(
      enableFormatter && dynamicRegistrations.rangeFormatting,
      Method.textDocument_rangeFormatting,
      DocumentRangeFormattingRegistrationOptions(
        documentSelector: [dartFiles], // This one is currently Dart-specific
      ),
    );
    register(
      dynamicRegistrations.definition,
      Method.textDocument_definition,
      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
    );
    register(
      dynamicRegistrations.typeDefinition,
      Method.textDocument_typeDefinition,
      TextDocumentRegistrationOptions(
        documentSelector: [dartFiles], // This one is currently Dart-specific
      ),
    );
    register(
      dynamicRegistrations.implementation,
      Method.textDocument_implementation,
      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
    );
    register(
      dynamicRegistrations.codeActions,
      Method.textDocument_codeAction,
      CodeActionRegistrationOptions(
        documentSelector: fullySupportedTypes,
        codeActionKinds: DartCodeActionKind.serverSupportedKinds,
      ),
    );
    register(
      dynamicRegistrations.rename,
      Method.textDocument_rename,
      RenameRegistrationOptions(
          documentSelector: fullySupportedTypes, prepareProvider: true),
    );
    register(
      dynamicRegistrations.folding,
      Method.textDocument_foldingRange,
      TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
    );
    register(
      dynamicRegistrations.fileOperations,
      Method.workspace_willRenameFiles,
      fileOperationRegistrationOptions,
    );
    register(
      dynamicRegistrations.didChangeConfiguration,
      Method.workspace_didChangeConfiguration,
    );
    register(
      dynamicRegistrations.selectionRange,
      Method.textDocument_selectionRange,
      SelectionRangeRegistrationOptions(
        documentSelector: [dartFiles],
      ),
    );
    register(
      dynamicRegistrations.semanticTokens,
      CustomMethods.semanticTokenDynamicRegistration,
      SemanticTokensRegistrationOptions(
        documentSelector: fullySupportedTypes,
        legend: semanticTokenLegend.lspLegend,
        full: Either2<bool, SemanticTokensOptionsFull>.t2(
          SemanticTokensOptionsFull(delta: false),
        ),
        range: Either2<bool, SemanticTokensOptionsRange>.t1(true),
      ),
    );

    await _applyRegistrations(registrations);
  }

  Future<void> _applyRegistrations(List<Registration> newRegistrations) async {
    // Compute a diff of old and new registrations to send the unregister or
    // another register request. We compare registrations by their methods and
    // the hashcode of their registration options to allow for multiple
    // registrations of a single method.

    String registrationHash(Registration registration) =>
        '${registration.method}${registration.registerOptions.hashCode}';

    final newRegistrationsMap = Map.fromEntries(
        newRegistrations.map((r) => MapEntry(r, registrationHash(r))));
    final newRegistrationsJsons = newRegistrationsMap.values.toSet();
    final currentRegistrationsMap = Map.fromEntries(
        currentRegistrations.map((r) => MapEntry(r, registrationHash(r))));
    final currentRegistrationJsons = currentRegistrationsMap.values.toSet();

    final registrationsToAdd = newRegistrationsMap.entries
        .where((entry) => !currentRegistrationJsons.contains(entry.value))
        .map((entry) => entry.key)
        .toList();

    final registrationsToRemove = currentRegistrationsMap.entries
        .where((entry) => !newRegistrationsJsons.contains(entry.value))
        .map((entry) => entry.key)
        .toList();

    // Update the current list before we start sending requests since we
    // go async.
    currentRegistrations
      ..removeAll(registrationsToRemove)
      ..addAll(registrationsToAdd);

    Future<void>? unregistrationRequest;
    if (registrationsToRemove.isNotEmpty) {
      final unregistrations = registrationsToRemove
          .map((r) => Unregistration(id: r.id, method: r.method))
          .toList();
      // It's important not to await this request here, as we must ensure
      // we cannot re-enter this method until we have sent both the unregister
      // and register requests to the client atomically.
      // https://github.com/dart-lang/sdk/issues/47851#issuecomment-988093109
      unregistrationRequest = _server.sendRequest(
          Method.client_unregisterCapability,
          UnregistrationParams(unregisterations: unregistrations));
    }

    Future<void>? registrationRequest;
    // Only send the registration request if we have at least one (since
    // otherwise we don't know that the client supports registerCapability).
    if (registrationsToAdd.isNotEmpty) {
      registrationRequest = _server
          .sendRequest(Method.client_registerCapability,
              RegistrationParams(registrations: registrationsToAdd))
          .then((registrationResponse) {
        final error = registrationResponse.error;
        if (error != null) {
          _server.logErrorToClient(
            'Failed to register capabilities with client: '
            '(${error.code}) '
            '${error.message}',
          );
        }
      });
    }

    // Only after we have sent both unregistration + registration events may
    // we await them, knowing another "thread" could not have executed this
    // method between them.
    await unregistrationRequest;
    await registrationRequest;
  }
}
