// 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 'package:analysis_server/protocol/protocol_generated.dart'
    show HoverInformation;
import 'package:analysis_server/src/computer/computer_documentation.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/element_locator.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:path/path.dart' as path;

/// Information about a library to display in a hover.
typedef _LibraryInfo = ({String? libraryName, String? libraryPath})?;
typedef _OffsetLength = ({int offset, int length});

/// A computer for the hover at the specified offset of a Dart
/// [CompilationUnit].
class DartUnitHoverComputer {
  final CompilationUnit _unit;
  final int _offset;
  final DocumentationPreference documentationPreference;
  final DartDocumentationComputer _documentationComputer;

  DartUnitHoverComputer(
    DartdocDirectiveInfo dartdocInfo,
    this._unit,
    this._offset, {
    this.documentationPreference = DocumentationPreference.full,
  }) : _documentationComputer = DartDocumentationComputer(dartdocInfo);

  /// Returns the computed hover, maybe `null`.
  HoverInformation? compute() {
    var node = _unit.nodeCovering(offset: _offset);
    if (node == null) {
      return null;
    }

    var locationEntity = _locationEntity(node, _offset);
    node = _targetNode(node);
    if (node == null || locationEntity == null) {
      return null;
    }

    if (node is CompilationUnitMember ||
        node is CatchClauseParameter ||
        node is Expression ||
        node is FormalParameter ||
        node is MethodDeclaration ||
        node is NamedType ||
        node is ConstructorDeclaration ||
        node is DeclaredIdentifier ||
        node is VariableDeclaration ||
        node is VariablePattern ||
        node is PatternFieldName ||
        node is PrimaryConstructorBody ||
        node is PrimaryConstructorDeclaration ||
        node is PrimaryConstructorName ||
        node is DartPattern ||
        (node is LibraryDirective && node.name == null) ||
        (node is SimpleIdentifier && node.parent is ImportDirective) ||
        node is ImportPrefixReference) {
      var range = _hoverRange(node, locationEntity);
      var hover = HoverInformation(range.offset, range.length);
      // element
      var element = ElementLocator.locate(node);
      if (element != null) {
        // short code that illustrates the element meaning.
        hover.elementDescription = _elementDisplayString(node, element);
        hover.elementKind = element.kind.displayName;
        hover.isDeprecated = element.isDeprecatedWithKind('use');
        // not local element
        if (element.enclosingElement is! ExecutableElement) {
          // containing class
          hover.containingClassDescription = _containingClass(element);
          // containing library
          var libraryInfo = _libraryInfo(element);
          hover.containingLibraryName = libraryInfo?.libraryName;
          hover.containingLibraryPath = libraryInfo?.libraryPath;
        }
        // documentation
        hover.dartdoc = _documentationComputer.computePreferred(
          element,
          documentationPreference,
        );
      }
      // parameter
      hover.parameter = _parameterDisplayString(node);
      // types
      hover.staticType = _typeDisplayString(node, element);
      // done
      return hover;
    }
    // not an expression
    return null;
  }

  /// Gets the name of the containing class of [element].
  String? _containingClass(Element element) {
    var containingClass = element.thisOrAncestorOfType<InterfaceElement>();
    return containingClass != null && containingClass != element
        ? containingClass.displayName
        : null;
  }

  /// Gets the display string for [element].
  ///
  /// This is usually `element.getDisplayString()` but may contain additional
  /// information to disambiguate things like constructors from types (and
  /// whether they are const).
  String? _elementDisplayString(AstNode node, Element? element) {
    var displayString = element?.displayString(multiline: true);

    if (displayString != null) {
      if (node is InstanceCreationExpression && node.keyword == null) {
        var prefix = node.isConst ? '(const) ' : '(new) ';
        displayString = prefix + displayString;
      } else if (node is DotShorthandConstructorInvocation) {
        var prefix = node.isConst ? '(const) ' : '(new) ';
        displayString = prefix + displayString;
      }
    }

    return displayString;
  }

  /// Computes the range this hover applies to.
  ///
  /// This is usually the range of [entity] but may be adjusted for entities
  /// like constructor names.
  _OffsetLength _hoverRange(AstNode node, SyntacticEntity entity) {
    // For constructors, the location should cover the type name and
    // constructor name (for both calls and declarations).
    if (node is InstanceCreationExpression) {
      return (
        offset: node.constructorName.offset,
        length: node.constructorName.length,
      );
    } else if (node is DotShorthandConstructorInvocation) {
      return (offset: node.offset, length: node.length);
    } else if (node is ConstructorDeclaration) {
      var offset =
          node.typeName?.offset ??
          node.newKeyword?.offset ??
          node.factoryKeyword!.offset;
      var end =
          node.name?.end ??
          node.typeName?.end ??
          node.newKeyword?.end ??
          node.factoryKeyword!.end;
      var length = end - offset;
      return (offset: offset, length: length);
    } else if (node is PrimaryConstructorDeclaration) {
      if (node.constructorName != null) {
        return (offset: entity.offset, length: entity.length);
      }
      var offset = node.typeName.offset;
      var end = node.typeName.end;
      var length = end - offset;
      return (offset: offset, length: length);
    } else {
      return (offset: entity.offset, length: entity.length);
    }
  }

  /// Returns information about the library that contains [element].
  _LibraryInfo _libraryInfo(Element element) {
    var library = element.library;
    if (library == null) {
      return null;
    }

    var definingSource = library.firstFragment.source;
    var uri = definingSource.uri;
    var analysisSession = _unit.declaredFragment?.element.session;

    String? libraryName, libraryPath;
    if (uri.isScheme('file') && analysisSession != null) {
      // for 'file:' URIs, use the path after the project root
      var context = analysisSession.resourceProvider.pathContext;
      var projectRootDir =
          analysisSession.analysisContext.contextRoot.root.path;
      var relativePath = context.relative(
        context.fromUri(uri),
        from: projectRootDir,
      );
      if (context.style == path.Style.windows) {
        var pathList = context.split(relativePath);
        libraryName = pathList.join('/');
      } else {
        libraryName = relativePath;
      }
    } else {
      libraryName = uri.toString();
    }
    libraryPath = definingSource.fullName;

    return (libraryName: libraryName, libraryPath: libraryPath);
  }

  /// Returns the [SyntacticEntity] that should be used as the range for this
  /// hover.
  ///
  /// Returns `null` if there is no valid entity for this hover.
  SyntacticEntity? _locationEntity(AstNode node, int offset) {
    return switch (node) {
      BinaryExpression() => node.operator,
      ConditionalExpression()
          when offset >= node.question.offset && offset <= node.question.end =>
        node.question,
      ConditionalExpression()
          when offset >= node.colon.offset && offset <= node.colon.end =>
        node.colon,
      AssignmentExpression() => node.operator,
      PrefixExpression() => node.operator,
      PostfixExpression() => node.operator,
      CatchClauseParameter() => node.name,
      ClassDeclaration() => node.namePart.typeName,
      ConstructorDeclaration() =>
        node.name ?? node.typeName ?? node.newKeyword ?? node.factoryKeyword,
      DeclaredIdentifier() => node.name,
      EnumDeclaration() => node.namePart.typeName,
      Expression() => node,
      ExtensionDeclaration() => node.name,
      ExtensionTypeDeclaration() => node.primaryConstructor.typeName,
      FormalParameter() => node.name,
      FunctionDeclaration() => node.name,
      ImportPrefixReference() => node.name,
      LibraryDirective() => node.libraryKeyword,
      MethodDeclaration() => node.name,
      MixinDeclaration() => node.name,
      NameWithTypeParameters() => node.typeName,
      NamedType() => node.name,
      PatternFieldName() => node.name,
      PrimaryConstructorBody() =>
        node.declaration?.constructorName ?? node.declaration?.typeName,
      PrimaryConstructorDeclaration() => node.constructorName ?? node.typeName,
      PrimaryConstructorName() => node.name,
      TypeAlias() => node.name,
      VariableDeclaration() => node.name,
      VariablePattern() => node.name,
      WildcardPattern() => node.name,
      _ => null,
    };
  }

  /// Gets the display string for the type of the parameter.
  ///
  /// Returns `null` if the parameter is not an expression.
  String? _parameterDisplayString(AstNode node) {
    if (node is! Expression) {
      return null;
    }
    var parameter = node.correspondingParameter;
    return switch (parameter?.enclosingElement) {
      // Expressions passed as arguments to setters and binary expressions
      // will have parameters here but we don't want them to show as such in
      // hovers because information about those functions are already available
      // by hovering over the function name or the operator.
      SetterElement() => null,
      MethodElement method when method.isOperator => null,
      _ => _elementDisplayString(node, parameter),
    };
  }

  /// Adjusts the target node for constructors.
  AstNode? _targetNode(AstNode node) {
    var parent = node.parent;
    var parent2 = parent?.parent;
    if (node is ClassNamePart) {
      return parent;
    } else if (parent is NamedType &&
        parent2 is ConstructorName &&
        parent2.parent is InstanceCreationExpression) {
      return parent2.parent;
    } else if (parent is ConstructorName &&
        parent2 is InstanceCreationExpression) {
      return parent2;
    } else if (node is SimpleIdentifier &&
        parent is ConstructorDeclaration &&
        parent.name != null) {
      return parent;
    } else if (node is SimpleIdentifier &&
        parent is DotShorthandConstructorInvocation) {
      return parent;
    }
    return node;
  }

  /// Returns information about the static type of [node].
  String? _typeDisplayString(AstNode node, Element? element) {
    var parent = node.parent;
    DartType? staticType;
    if (node is Expression &&
        (element == null ||
            element is VariableElement ||
            element is GetterElement ||
            element is SetterElement)) {
      staticType = _getTypeOfDeclarationOrReference(node);
    } else if (element is VariableElement) {
      staticType = element.type;
    } else if (parent is MethodInvocation && parent.methodName == node) {
      staticType = parent.staticInvokeType;
      if (staticType != null && staticType is DynamicType) {
        staticType = null;
      }
    } else if (parent is PrefixedIdentifier && parent.identifier == node) {
      staticType = parent.identifier.staticType;
      if (staticType != null && staticType is DynamicType) {
        staticType = null;
      }
    } else if (parent is DotShorthandInvocation && parent.memberName == node) {
      staticType = parent.staticInvokeType;
      if (staticType != null && staticType is DynamicType) {
        staticType = null;
      }
    } else if (node is PatternFieldName && parent is PatternField) {
      staticType = parent.pattern.matchedValueType;
    } else if (node is DartPattern) {
      staticType = node.matchedValueType;
    }
    return staticType?.getDisplayString();
  }

  static DartType? _getTypeOfDeclarationOrReference(Expression node) {
    if (node is SimpleIdentifier) {
      var element = node.element;
      if (element is VariableElement) {
        if (node.inDeclarationContext()) {
          return element.type;
        }
        var parent2 = node.parent?.parent;
        if (parent2 is NamedExpression && parent2.name.label == node) {
          return element.type;
        }
      }
      var parent = node.parent;
      var parent2 = parent?.parent;

      if (parent is AssignmentExpression && parent.leftHandSide == node) {
        // Direct setter reference
        return parent.writeType;
      } else if (parent2 is AssignmentExpression &&
          parent2.leftHandSide == parent) {
        if (parent is PrefixedIdentifier && parent.identifier == node) {
          // Prefixed setter (`myInstance.foo =`)
          return parent2.writeType;
        } else if (parent is PropertyAccess && parent.propertyName == node) {
          // Expression prefix (`A<int>().foo =`)
          return parent2.writeType;
        }
      }
    }
    return node.staticType;
  }
}
