// Copyright (c) 2018, 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_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
import 'package:analysis_server/src/computer/computer_signature.dart';
import 'package:analysis_server/src/computer/computer_type_arguments_signature.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';

class SignatureHelpHandler
    extends MessageHandler<SignatureHelpParams, SignatureHelp?> {
  SignatureHelpHandler(LspAnalysisServer server) : super(server);
  @override
  Method get handlesMessage => Method.textDocument_signatureHelp;

  @override
  LspJsonHandler<SignatureHelpParams> get jsonHandler =>
      SignatureHelpParams.jsonHandler;

  @override
  Future<ErrorOr<SignatureHelp?>> handle(
      SignatureHelpParams params, CancellationToken token) async {
    if (!isDartDocument(params.textDocument)) {
      return success(null);
    }

    final clientCapabilities = server.clientCapabilities;
    if (clientCapabilities == null) {
      // This should not happen unless a client misbehaves.
      return serverNotInitializedError;
    }

    // If triggered automatically by pressing the trigger character, we will
    // only provide results if the character we typed was the one that actually
    // starts the argument list. This is to avoid popping open signature help
    // whenever the user types a `(` that might not be the start of an argument
    // list, as the client does not have any context and will always send the
    // request.
    final autoTriggered = params.context?.triggerKind ==
            SignatureHelpTriggerKind.TriggerCharacter &&
        // Retriggers can be ignored (treated as manual invocations) as it's
        // fine to always generate results if the signature help is already
        // visible on the client (it will just update, it doesn't pop up new UI).
        params.context?.isRetrigger == false;

    final pos = params.position;
    final path = pathOfDoc(params.textDocument);
    final unit = await path.mapResult(requireResolvedUnit);
    final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));

    return offset.mapResult((offset) {
      final formats = clientCapabilities.signatureHelpDocumentationFormats;
      final dartDocInfo = server.getDartdocDirectiveInfoFor(unit.result);

      // First check if we're in a type args list and if so build some
      // signature help for that.
      final typeArgsSignature = _tryGetTypeArgsSignatureHelp(
        dartDocInfo,
        unit.result.unit,
        offset,
        autoTriggered,
        formats,
      );
      if (typeArgsSignature != null) {
        return success(typeArgsSignature);
      }

      final computer =
          DartUnitSignatureComputer(dartDocInfo, unit.result.unit, offset);
      if (!computer.offsetIsValid) {
        return success(null); // No error, just no valid hover.
      }
      final signature = computer.compute();
      if (signature == null) {
        return success(null); // No error, just no valid hover.
      }

      // Skip results if this was an auto-trigger but not from the start of the
      // argument list.
      // The ArgumentList's offset is before the paren, but the request offset
      // will be after.
      if (autoTriggered && offset != computer.argumentList.offset + 1) {
        return success(null);
      }

      return success(toSignatureHelp(formats, signature));
    });
  }

  /// Tries to create signature information for a surrounding [TypeArgumentList].
  ///
  /// Returns `null` if [offset] is in an invalid location, not inside a type
  /// argument list or was auto-triggered in a location that was not the start
  /// of a type argument list.
  SignatureHelp? _tryGetTypeArgsSignatureHelp(
    DartdocDirectiveInfo dartDocInfo,
    CompilationUnit unit,
    int offset,
    bool autoTriggered,
    Set<MarkupKind>? formats,
  ) {
    final typeArgsComputer =
        DartTypeArgumentsSignatureComputer(dartDocInfo, unit, offset, formats);
    if (!typeArgsComputer.offsetIsValid) {
      return null;
    }

    final typeSignature = typeArgsComputer.compute();
    if (typeSignature == null) {
      return null;
    }

    // If auto-triggered from typing a `<`, only show if that `<` was at
    // the start of the arg list (to avoid triggering on other `<`s).
    if (autoTriggered && offset != typeArgsComputer.argumentList.offset + 1) {
      return null;
    }

    return typeSignature;
  }
}
