// Copyright (c) 2021, 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';

/// Wraps the client (editor) capabilities to improve performance.
///
/// Sets transferred as arrays in JSON will be converted to Sets for faster
/// lookups and default values and nulls will be handled here.
class LspClientCapabilities {
  /// If the client does not provide capabilities.completion.completionItemKind.valueSet
  /// then we must never send a kind that's not in this list.
  static final Set<CompletionItemKind> defaultSupportedCompletionKinds = {
    CompletionItemKind.Text,
    CompletionItemKind.Method,
    CompletionItemKind.Function,
    CompletionItemKind.Constructor,
    CompletionItemKind.Field,
    CompletionItemKind.Variable,
    CompletionItemKind.Class,
    CompletionItemKind.Interface,
    CompletionItemKind.Module,
    CompletionItemKind.Property,
    CompletionItemKind.Unit,
    CompletionItemKind.Value,
    CompletionItemKind.Enum,
    CompletionItemKind.Keyword,
    CompletionItemKind.Snippet,
    CompletionItemKind.Color,
    CompletionItemKind.File,
    CompletionItemKind.Reference,
  };

  /// If the client does not provide capabilities.documentSymbol.symbolKind.valueSet
  /// then we must never send a kind that's not in this list.
  static final Set<SymbolKind> defaultSupportedSymbolKinds = {
    SymbolKind.File,
    SymbolKind.Module,
    SymbolKind.Namespace,
    SymbolKind.Package,
    SymbolKind.Class,
    SymbolKind.Method,
    SymbolKind.Property,
    SymbolKind.Field,
    SymbolKind.Constructor,
    SymbolKind.Enum,
    SymbolKind.Interface,
    SymbolKind.Function,
    SymbolKind.Variable,
    SymbolKind.Constant,
    SymbolKind.Str,
    SymbolKind.Number,
    SymbolKind.Boolean,
    SymbolKind.Array,
  };

  final ClientCapabilities raw;
  final bool documentChanges;
  final bool configuration;
  final bool createResourceOperations;
  final bool renameResourceOperations;
  final bool completionDeprecatedFlag;
  final bool applyEdit;
  final bool workDoneProgress;
  final bool completionSnippets;
  final bool renameValidation;
  final bool literalCodeActions;
  final bool insertReplaceCompletionRanges;
  final bool definitionLocationLink;
  final bool typeDefinitionLocationLink;
  final bool hierarchicalSymbols;
  final bool diagnosticCodeDescription;
  final Set<CodeActionKind> codeActionKinds;
  final Set<CompletionItemTag> completionItemTags;
  final Set<DiagnosticTag> diagnosticTags;
  final Set<MarkupKind>? completionDocumentationFormats;
  final Set<MarkupKind>? signatureHelpDocumentationFormats;
  final Set<MarkupKind>? hoverContentFormats;
  final Set<SymbolKind> documentSymbolKinds;
  final Set<SymbolKind> workspaceSymbolKinds;
  final Set<CompletionItemKind> completionItemKinds;
  final Set<InsertTextMode> completionInsertTextModes;
  final bool experimentalSnippetTextEdit;

  LspClientCapabilities(this.raw)
      : applyEdit = raw.workspace?.applyEdit ?? false,
        codeActionKinds = _listToSet(raw.textDocument?.codeAction
            ?.codeActionLiteralSupport?.codeActionKind.valueSet),
        completionDeprecatedFlag =
            raw.textDocument?.completion?.completionItem?.deprecatedSupport ??
                false,
        completionDocumentationFormats = _completionDocumentationFormats(raw),
        completionInsertTextModes = _listToSet(raw.textDocument?.completion
            ?.completionItem?.insertTextModeSupport?.valueSet),
        completionItemKinds = _listToSet(
            raw.textDocument?.completion?.completionItemKind?.valueSet,
            defaults: defaultSupportedCompletionKinds),
        completionSnippets =
            raw.textDocument?.completion?.completionItem?.snippetSupport ??
                false,
        configuration = raw.workspace?.configuration ?? false,
        createResourceOperations = raw
                .workspace?.workspaceEdit?.resourceOperations
                ?.contains(ResourceOperationKind.Create) ??
            false,
        renameResourceOperations = raw
                .workspace?.workspaceEdit?.resourceOperations
                ?.contains(ResourceOperationKind.Rename) ??
            false,
        definitionLocationLink =
            raw.textDocument?.definition?.linkSupport ?? false,
        typeDefinitionLocationLink =
            raw.textDocument?.typeDefinition?.linkSupport ?? false,
        completionItemTags = _listToSet(
            raw.textDocument?.completion?.completionItem?.tagSupport?.valueSet),
        diagnosticTags = _listToSet(
            raw.textDocument?.publishDiagnostics?.tagSupport?.valueSet),
        documentChanges =
            raw.workspace?.workspaceEdit?.documentChanges ?? false,
        documentSymbolKinds = _listToSet(
            raw.textDocument?.documentSymbol?.symbolKind?.valueSet,
            defaults: defaultSupportedSymbolKinds),
        hierarchicalSymbols = raw.textDocument?.documentSymbol
                ?.hierarchicalDocumentSymbolSupport ??
            false,
        diagnosticCodeDescription =
            raw.textDocument?.publishDiagnostics?.codeDescriptionSupport ??
                false,
        hoverContentFormats = _hoverContentFormats(raw),
        insertReplaceCompletionRanges = raw.textDocument?.completion
                ?.completionItem?.insertReplaceSupport ??
            false,
        literalCodeActions =
            raw.textDocument?.codeAction?.codeActionLiteralSupport != null,
        renameValidation = raw.textDocument?.rename?.prepareSupport ?? false,
        signatureHelpDocumentationFormats = _sigHelpDocumentationFormats(raw),
        workDoneProgress = raw.window?.workDoneProgress ?? false,
        workspaceSymbolKinds = _listToSet(
            raw.workspace?.symbol?.symbolKind?.valueSet,
            defaults: defaultSupportedSymbolKinds),
        experimentalSnippetTextEdit =
            raw.experimental is Map<String, Object?> &&
                (raw.experimental as Map<String, Object?>)['snippetTextEdit'] ==
                    true;

  static Set<MarkupKind>? _completionDocumentationFormats(
      ClientCapabilities raw) {
    // For formats, null is valid (which means only raw strings are supported,
    // not [MarkupContent]).
    return _listToNullableSet(
        raw.textDocument?.completion?.completionItem?.documentationFormat);
  }

  static Set<MarkupKind>? _hoverContentFormats(ClientCapabilities raw) {
    // For formats, null is valid (which means only raw strings are supported,
    // not [MarkupContent]), so use null as default.
    return _listToNullableSet(raw.textDocument?.hover?.contentFormat);
  }

  /// Converts a list to a `Set`, returning null if the list is null.
  static Set<T>? _listToNullableSet<T>(List<T>? items) {
    return items != null ? {...items} : null;
  }

  /// Converts a list to a `Set`, returning [defaults] if the list is null.
  ///
  /// If [defaults] is not supplied, will return an empty set.
  static Set<T> _listToSet<T>(List<T>? items, {Set<T> defaults = const {}}) {
    return items != null ? {...items} : defaults;
  }

  static Set<MarkupKind>? _sigHelpDocumentationFormats(ClientCapabilities raw) {
    // For formats, null is valid (which means only raw strings are supported,
    // not [MarkupContent]), so use null as default.
    return _listToNullableSet(raw.textDocument?.signatureHelp
        ?.signatureInformation?.documentationFormat);
  }
}
