// 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/src/services/correction/fix/data_driven/element_descriptor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart'
    show ClassElement, ExtensionElement, PrefixElement;
import 'package:analyzer/dart/element/type.dart';

/// An object that can be used to determine whether an element is appropriate
/// for a given reference.
class ElementMatcher {
  /// The URIs of the libraries that are imported in the library containing the
  /// reference.
  final List<Uri> importedUris;

  /// The components of the element being referenced. The components are ordered
  /// from the most local to the most global.
  final List<String> components;

  /// A list of the kinds of elements that are appropriate for some given
  /// location in the code An empty list represents all kinds rather than no
  /// kinds.
  final List<ElementKind> validKinds;

  /// Initialize a newly created matcher representing a reference to an element
  /// with the given [name] in a library that imports the [importedUris].
  ElementMatcher(
      {required this.importedUris,
      required this.components,
      List<ElementKind>? kinds})
      : assert(components.isNotEmpty),
        validKinds = kinds ?? const [];

  /// Return `true` if this matcher matches the given [element].
  bool matches(ElementDescriptor element) {
    //
    // Check that the components in the element's name match the node.
    //
    // This algorithm is probably too general given that there will currently
    // always be either one or two components.
    //
    var elementComponents = element.components;
    var elementComponentCount = elementComponents.length;
    var nodeComponentCount = components.length;
    if (nodeComponentCount == elementComponentCount) {
      // The component counts are the same, so we can just compare the two
      // lists.
      for (var i = 0; i < nodeComponentCount; i++) {
        if (elementComponents[i] != components[i]) {
          return false;
        }
      }
    } else if (nodeComponentCount < elementComponentCount) {
      // The node has fewer components, which can happen, for example, when we
      // can't figure out the class that used to define a field. We treat the
      // missing components as wildcards and match the rest.
      for (var i = 0; i < nodeComponentCount; i++) {
        if (elementComponents[i] != components[i]) {
          return false;
        }
      }
    } else {
      // The node has more components than the element, which can happen when a
      // constructor is implicitly renamed because the class was renamed.
      // TODO(brianwilkerson) Figure out whether we want to support this or
      //  whether we want to require fix data authors to explicitly include the
      //  change to the constructor. On the one hand it's more work for the
      //  author, on the other hand it give us more data so we're less likely to
      //  make apply a fix in invalid circumstances.
      if (elementComponents[0] != components[1]) {
        return false;
      }
    }
    //
    // Check whether the kind of element matches the possible kinds that the
    // node might have.
    //
    if (validKinds.isNotEmpty && !validKinds.contains(element.kind)) {
      return false;
    }
    //
    // Check whether the element is in an imported library.
    //
    var libraryUris = element.libraryUris;
    for (var importedUri in importedUris) {
      if (libraryUris.contains(importedUri)) {
        return true;
      }
    }
    return false;
  }

  /// Return an element matcher that will match the element that is, or should
  /// be, associated with the given [node], or `null` if there is no appropriate
  /// matcher for the node.
  static ElementMatcher? forNode(AstNode? node) {
    if (node == null) {
      return null;
    }
    var importedUris = _importElementsForNode(node);
    if (importedUris == null) {
      return null;
    }
    var components = _componentsForNode(node);
    if (components == null) {
      return null;
    }
    return ElementMatcher(
        importedUris: importedUris,
        components: components,
        kinds: _kindsForNode(node));
  }

  /// Return the components of the path of the element associated with the given
  /// [node]. The components are ordered from the most local to the most global.
  /// For example, for a constructor this would be the name of the constructor
  /// followed by the name of the class in which the constructor is declared
  /// (with an empty string for the unnamed constructor).
  static List<String>? _componentsForNode(AstNode? node) {
    if (node is SimpleIdentifier) {
      var parent = node.parent;
      if (parent is Label && parent.parent is NamedExpression) {
        // The parent of the named expression is an argument list. Because we
        // don't represent parameters as elements, the element we need to match
        // against is the invocation containing those arguments.
        return _componentsFromParent(parent.parent!.parent!);
      } else if (parent is NamedType && parent.parent is ConstructorName) {
        return ['', node.name];
      } else if (parent is MethodDeclaration && node == parent.name) {
        return [node.name];
      } else if ((parent is MethodInvocation &&
              node == parent.methodName &&
              !_isPrefix(parent.target)) ||
          (parent is PrefixedIdentifier &&
              node == parent.identifier &&
              !_isPrefix(parent.prefix)) ||
          (parent is PropertyAccess &&
              node == parent.propertyName &&
              !_isPrefix(parent.target))) {
        return _componentsFromParent(node);
      }
      return _componentsFromIdentifier(node);
    } else if (node is PrefixedIdentifier) {
      var parent = node.parent;
      if (parent is NamedType && parent.parent is ConstructorName) {
        return ['', node.identifier.name];
      }
      return [node.identifier.name];
    } else if (node is ConstructorName) {
      var constructorName = node.name;
      if (constructorName != null) {
        return [constructorName.name];
      }
    } else if (node is NamedType) {
      return [node.name.name];
    } else if (node is TypeArgumentList) {
      return _componentsFromParent(node);
    } else if (node is ArgumentList) {
      return _componentsFromParent(node);
    }
    var parent = node?.parent;
    if (parent is ArgumentList) {
      return _componentsFromParent(parent);
    }
    return null;
  }

  /// Return the components associated with the [identifier] when there is no
  /// contextual information.
  static List<String> _componentsFromIdentifier(SimpleIdentifier identifier) {
    var element = identifier.staticElement;
    if (element == null) {
      var parent = identifier.parent;
      if (parent is AssignmentExpression && identifier == parent.leftHandSide) {
        element = parent.writeElement;
      }
    }
    if (element != null) {
      var enclosingElement = element.enclosingElement;
      if (enclosingElement is ClassElement) {
        return [identifier.name, enclosingElement.name];
      } else if (enclosingElement is ExtensionElement) {
        var name = enclosingElement.name;
        if (name != null) {
          return [identifier.name, name];
        }
      }
    }
    return [identifier.name];
  }

  /// Return the components for the element associated with the given [node] by
  /// looking at the parent of the [node].
  static List<String>? _componentsFromParent(AstNode node) {
    var parent = node.parent;
    if (parent is ArgumentList) {
      parent = parent.parent;
    }
    if (parent is Annotation) {
      return [parent.constructorName?.name ?? '', parent.name.name];
    } else if (parent is ExtensionOverride) {
      return [parent.extensionName.name];
    } else if (parent is InstanceCreationExpression) {
      var constructorName = parent.constructorName;
      return [
        constructorName.name?.name ?? '',
        constructorName.type2.name.name
      ];
    } else if (parent is MethodInvocation) {
      var methodName = parent.methodName;
      var targetName = _nameOfTarget(parent.realTarget);
      if (targetName != null) {
        return [methodName.name, targetName];
      }
      return _componentsFromIdentifier(methodName);
    } else if (parent is PrefixedIdentifier) {
      var identifier = parent.identifier;
      var targetName = _nameOfTarget(parent.prefix);
      if (targetName != null) {
        return [identifier.name, targetName];
      }
      return _componentsFromIdentifier(identifier);
    } else if (parent is PropertyAccess) {
      var propertyName = parent.propertyName;
      var targetName = _nameOfTarget(parent.realTarget);
      if (targetName != null) {
        return [propertyName.name, targetName];
      }
      return _componentsFromIdentifier(propertyName);
    } else if (parent is RedirectingConstructorInvocation) {
      var ancestor = parent.parent;
      if (ancestor is ConstructorDeclaration) {
        return [parent.constructorName?.name ?? '', ancestor.returnType.name];
      }
    } else if (parent is SuperConstructorInvocation) {
      var ancestor = parent.parent;
      if (ancestor is ConstructorDeclaration) {
        return [parent.constructorName?.name ?? '', ancestor.returnType.name];
      }
    }
    return null;
  }

  /// Return the URIs of the imports in the library containing the [node], or
  /// `null` if the imports can't be determined.
  static List<Uri>? _importElementsForNode(AstNode node) {
    var root = node.root;
    if (root is! CompilationUnit) {
      return null;
    }
    var importedUris = <Uri>[];
    var library = root.declaredElement?.library;
    if (library == null) {
      return null;
    }
    for (var importElement in library.imports) {
      // TODO(brianwilkerson) Filter based on combinators to help avoid making
      //  invalid suggestions.
      var uri = importElement.importedLibrary?.source.uri;
      if (uri != null) {
        // The [uri] is `null` if the literal string is not a valid URI.
        importedUris.add(uri);
      }
    }
    return importedUris;
  }

  /// Return `true` if the [node] is a prefix
  static bool _isPrefix(AstNode? node) {
    return node is SimpleIdentifier && node.staticElement is PrefixElement;
  }

  /// Return the kinds of elements that could reasonably be referenced at the
  /// location of the [node]. If [child] is not `null` then the [node] is a
  /// parent of the [child].
  static List<ElementKind>? _kindsForNode(AstNode? node, {AstNode? child}) {
    if (node is ConstructorName) {
      return const [ElementKind.constructorKind];
    } else if (node is ExtensionOverride) {
      return const [ElementKind.extensionKind];
    } else if (node is InstanceCreationExpression) {
      return const [ElementKind.constructorKind];
    } else if (node is Label) {
      var argumentList = node.parent?.parent;
      return _kindsForNode(argumentList?.parent, child: argumentList);
    } else if (node is MethodInvocation) {
      assert(child != null);
      if (node.target == child) {
        return const [
          ElementKind.classKind,
          ElementKind.enumKind,
          ElementKind.mixinKind
        ];
      }
      var realTarget = node.realTarget;
      if (realTarget != null && !_isPrefix(realTarget)) {
        return const [ElementKind.constructorKind, ElementKind.methodKind];
      }
      return const [
        ElementKind.classKind,
        ElementKind.extensionKind,
        ElementKind.functionKind,
        ElementKind.methodKind
      ];
    } else if (node is NamedType) {
      var parent = node.parent;
      if (parent is ConstructorName && parent.name == null) {
        return const [ElementKind.classKind, ElementKind.constructorKind];
      }
      return const [
        ElementKind.classKind,
        ElementKind.enumKind,
        ElementKind.mixinKind,
        ElementKind.typedefKind
      ];
    } else if (node is PrefixedIdentifier) {
      var prefix = node.prefix;
      if (prefix == child) {
        return const [
          ElementKind.classKind,
          ElementKind.enumKind,
          ElementKind.extensionKind,
          ElementKind.mixinKind,
          ElementKind.typedefKind
        ];
      } else if (prefix.staticElement is PrefixElement) {
        var parent = node.parent;
        if ((parent is NamedType && parent.parent is! ConstructorName) ||
            (parent is PropertyAccess && parent.target == node)) {
          return const [
            ElementKind.classKind,
            ElementKind.enumKind,
            ElementKind.extensionKind,
            ElementKind.mixinKind,
            ElementKind.typedefKind
          ];
        }
        return const [
          // If the old class has been removed then this might have been a
          // constructor invocation.
          ElementKind.constructorKind,
          ElementKind.getterKind,
          ElementKind.setterKind,
          ElementKind.variableKind
        ];
      }
      return const [
        ElementKind.fieldKind,
        ElementKind.getterKind,
        ElementKind.setterKind
      ];
    } else if (node is PropertyAccess) {
      return const [
        ElementKind.fieldKind,
        ElementKind.getterKind,
        ElementKind.setterKind
      ];
    } else if (node is SimpleIdentifier) {
      return _kindsForNode(node.parent, child: node);
    }
    return null;
  }

  /// Return the name of the class associated with the given [target].
  static String? _nameOfTarget(Expression? target) {
    if (target is SimpleIdentifier) {
      var type = target.staticType;
      if (type != null) {
        if (type is InterfaceType) {
          return type.element.name;
        } else if (type.isDynamic) {
          // The name is likely to be undefined.
          return target.name;
        }
        return null;
      }
      return target.name;
    } else if (target != null) {
      var type = target.staticType;
      if (type is InterfaceType) {
        return type.element.name;
      }
      return null;
    }
    return null;
  }
}
