// 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_kind.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart' show ClassElement;
import 'package:analyzer/dart/element/type.dart';

/// A description of an element.
class ElementDescriptor {
  /// The URIs of the library in which the element is defined.
  final List<Uri> libraryUris;

  /// The kind of element that was changed.
  final ElementKind kind;

  /// A flag indicating whether the element is a static member of a container
  /// such as a class, enum, mixin, or extension.
  ///
  /// The flag should be `false` for top-level declarations. The implication is
  /// that the flag will only be true if the list of [components] has more than
  /// one element.
  final bool isStatic;

  /// The components that uniquely identify the element within its library. The
  /// components are ordered from the most local to the most global.
  final List<String> components;

  /// Initialize a newly created element descriptor to describe an element
  /// accessible via any of the [libraryUris] where the path to the element
  /// within the library is given by the list of [components]. The [kind] of the
  /// element is represented by the key used in the data file.
  ElementDescriptor(
      {required this.libraryUris,
      required this.kind,
      required this.isStatic,
      required this.components});

  /// Return `true` if the described element is a constructor.
  bool get isConstructor => kind == ElementKind.constructorKind;

  /// Return `true` if the given [node] appears to be consistent with the
  /// element being described.
  bool matches(AstNode node) {
    // TODO(brianwilkerson) Check the resolved element, if one exists, for more
    //  accurate results.
    switch (kind) {
      case ElementKind.classKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
      case ElementKind.constantKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
      case ElementKind.constructorKind:
        return _matchesConstructor(node);
      case ElementKind.enumKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
      case ElementKind.extensionKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
      case ElementKind.fieldKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
      case ElementKind.functionKind:
        return _matchesFunction(node);
      case ElementKind.getterKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
      case ElementKind.methodKind:
        return _matchesMethod(node);
      case ElementKind.mixinKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
      case ElementKind.setterKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
      case ElementKind.typedefKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
      case ElementKind.variableKind:
        // TODO(brianwilkerson) Handle this case.
        return false;
    }
  }

  /// Return `true` if the given [node] appears to be consistent with the
  /// constructor being described.
  bool _matchesConstructor(AstNode node) {
    if (node is Annotation) {
      var className = _nameFromIdentifier(node.name);
      var constructorName = node.constructorName ?? '';
      if (components[0] == constructorName && components[1] == className) {
        return true;
      }
    } else if (node is InstanceCreationExpression) {
      var name = node.constructorName;
      var className = _nameFromIdentifier(name.type.name);
      var constructorName = name.name?.name ?? '';
      if (components[0] == constructorName && components[1] == className) {
        return true;
      }
    } else if (node is MethodInvocation) {
      var target = node.target;
      if (target == null) {
        if (components[0] == '' && components[1] == node.methodName.name) {
          return true;
        }
      } else if (target is Identifier) {
        var className = _nameFromIdentifier(target);
        var constructorName = node.methodName.name;
        if (components[0] == constructorName && components[1] == className) {
          return true;
        }
      }
    }
    return false;
  }

  /// Return `true` if the given [node] appears to be consistent with the
  /// function being described.
  bool _matchesFunction(AstNode node) {
    if (node is MethodInvocation) {
      if (node.realTarget == null && components[0] == node.methodName.name) {
        return true;
      }
    }
    return false;
  }

  /// Return `true` if the given [node] appears to be consistent with the
  /// method being described.
  bool _matchesMethod(AstNode node) {
    if (node is MethodInvocation) {
      if (components[0] == node.methodName.name) {
        var target = node.realTarget;
        if (target == null) {
          // TODO(brianwilkerson) If `node.target == null` then the invocation
          //  should be in a subclass of the element's class.
          return true;
        } else {
          var type = target.staticType;
          if (type == null && target is SimpleIdentifier) {
            var element = target.staticElement;
            // TODO(brianwilkerson) Handle more than `ClassElement`.
            if (element is ClassElement) {
              type = element.thisType;
            }
          }
          if (type == null) {
            // We can't get more specific type information, so we assume
            // that the method might have been in the element's class.
            return true;
          }
          if (components[1] == type.element?.name) {
            return true;
          }
          if (type is InterfaceType) {
            for (var supertype in type.allSupertypes) {
              if (components[1] == supertype.element.name) {
                return true;
              }
            }
          }
        }
      }
    }
    return false;
  }

  String _nameFromIdentifier(Identifier identifier) {
    if (identifier is SimpleIdentifier) {
      return identifier.name;
    } else if (identifier is PrefixedIdentifier) {
      return identifier.identifier.name;
    }
    throw StateError(
        'Unexpected class of identifier: ${identifier.runtimeType}');
  }
}
