// Copyright (c) 2022, 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/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart' show ElementImpl;
import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
import 'package:analyzer_plugin/utilities/analyzer_converter.dart';

typedef _LocationsOrLinks = Either2<List<Location>, List<LocationLink>>;

class TypeDefinitionHandler
    extends MessageHandler<TypeDefinitionParams, _LocationsOrLinks>
    with LspPluginRequestHandlerMixin {
  static const _emptyResult = _LocationsOrLinks.t1([]);

  TypeDefinitionHandler(super.server);

  @override
  Method get handlesMessage => Method.textDocument_typeDefinition;

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

  @override
  Future<ErrorOr<_LocationsOrLinks>> handle(TypeDefinitionParams params,
      MessageInfo message, CancellationToken token) async {
    if (!isDartDocument(params.textDocument)) {
      return success(_emptyResult);
    }

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

    /// Whether the client supports `LocationLink` results instead of the
    /// original `Location`. `LocationLink`s can include an additional `Range`
    /// to distinguish between codeRange and nameRange (selectionRange), and
    /// also an `originSelectionRange` that tells the client which range the
    /// result is valid for.
    final supportsLocationLink = clientCapabilities.typeDefinitionLocationLink;
    final pos = params.position;
    final path = pathOfDoc(params.textDocument);

    return path.mapResult((path) async {
      final result = await server.getResolvedUnit(path);
      if (result == null) {
        return success(_emptyResult);
      }

      final offset = toOffset(result.lineInfo, pos);
      return offset.mapResult((offset) async {
        final node = NodeLocator(offset).searchWithin(result.unit);
        if (node == null) {
          return success(_emptyResult);
        }

        final type = node is Expression ? _getType(node) : null;
        final element = type?.element;
        if (element is! ElementImpl) {
          return success(_emptyResult);
        }

        // Obtain a `LineInfo` for the targets file to map offsets.
        final targetUnitElement =
            element.thisOrAncestorOfType<CompilationUnitElement>();
        final targetLineInfo = targetUnitElement?.lineInfo;
        if (targetLineInfo == null) {
          return success(_emptyResult);
        }

        final converter = AnalyzerConverter();
        final location = converter.locationFromElement(element);
        if (location == null) {
          return success(_emptyResult);
        }

        if (supportsLocationLink) {
          return success(_LocationsOrLinks.t2([
            _toLocationLink(
                result.lineInfo, targetLineInfo, node, element, location)
          ]));
        } else {
          return success(
              _LocationsOrLinks.t1([_toLocation(location, targetLineInfo)]));
        }
      });
    });
  }

  /// Creates an LSP [Location] for the server [location].
  Location _toLocation(plugin.Location location, LineInfo lineInfo) {
    return Location(
      uri: Uri.file(location.file).toString(),
      range: toRange(lineInfo, location.offset, location.length),
    );
  }

  /// Creates an LSP [LocationLink] for the server [targetLocation].
  ///
  /// Uses [originLineInfo] and [originNode] to compute `originSelectionRange`
  /// and [targetLineInfo] and [targetElement] for code ranges.
  LocationLink _toLocationLink(
    LineInfo originLineInfo,
    LineInfo targetLineInfo,
    AstNode originNode,
    ElementImpl targetElement,
    plugin.Location targetLocation,
  ) {
    final nameRange =
        toRange(targetLineInfo, targetLocation.offset, targetLocation.length);

    final codeOffset = targetElement.codeOffset;
    final codeLength = targetElement.codeLength;
    final codeRange = codeOffset != null && codeLength != null
        ? toRange(targetLineInfo, codeOffset, codeLength)
        : nameRange;

    return LocationLink(
      originSelectionRange:
          toRange(originLineInfo, originNode.offset, originNode.length),
      targetUri: Uri.file(targetLocation.file).toString(),
      targetRange: codeRange,
      targetSelectionRange: nameRange,
    );
  }

  /// Returns the [DartType] most appropriate for navigating to from [node] when
  /// invoking Go to Type Definition.
  static DartType? _getType(Expression node) {
    if (node is SimpleIdentifier) {
      final element = node.staticElement;
      if (element is ClassElement) {
        return element.thisType;
      } else if (element is VariableElement) {
        if (node.inDeclarationContext()) {
          return element.type;
        }
        final parent = node.parent?.parent;
        if (parent is NamedExpression && parent.name.label == node) {
          return element.type;
        }
      } else if (node.inSetterContext()) {
        final writeElement = node.writeElement;
        if (writeElement is PropertyAccessorElement) {
          return writeElement.variable.type;
        }
      }
    }

    return node.staticType;
  }
}
