// 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;
import 'package:analyzer/dart/element/type.dart';
import 'package:meta/meta.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 != null && 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 TypeName && 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) ||
          (parent is PrefixedIdentifier && node == parent.identifier) ||
          (parent is PropertyAccess && node == parent.propertyName)) {
        return _componentsFromParent(node);
      }
      return _componentsFromIdentifier(node);
    } else if (node is PrefixedIdentifier) {
      var parent = node.parent;
      if (parent is TypeName && parent.parent is ConstructorName) {
        return ['', node.identifier.name];
      }
      return [node.identifier.name];
    } else if (node is ConstructorName) {
      return [node.name.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);
    } else if (node?.parent is ArgumentList) {
      return _componentsFromParent(node.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 ||
          enclosingElement is ExtensionElement) {
        return [identifier.name, enclosingElement.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.type.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 as CompilationUnit).declaredElement.library;
    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 the kinds of elements that could reasonably be referenced at the
  /// location of the [node]. If [child] is no `null` then the [node] is a
  /// parent of the original node.
  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
        ];
      } else if (node.realTarget != null) {
        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) {
      if (node.prefix == child) {
        return const [
          ElementKind.classKind,
          ElementKind.enumKind,
          ElementKind.extensionKind,
          ElementKind.mixinKind,
          ElementKind.typedefKind
        ];
      }
      return const [
        ElementKind.fieldKind,
        ElementKind.getterKind,
        ElementKind.setterKind
      ];
    } else if (node is PropertyAccess) {
      return const [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;
  }
}
