// 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/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/util/performance/operation_performance.dart';

/// Returns direct children of [parent].
List<Element> getChildren(Element parent, [String? name]) {
  var children = <Element>[];
  visitChildren(parent, (element) {
    if (name == null || element.name3 == name) {
      children.add(element);
    }
    return false;
  });
  return children;
}

/// Returns direct non-synthetic children of the given [InterfaceElement].
///
/// Includes: fields, accessors and methods.
/// Excludes: constructors and synthetic elements.
List<Element> getClassMembers(InterfaceElement clazz, [String? name]) {
  var members = <Element>[];
  visitChildren(clazz, (Element element) {
    if (element.isSynthetic) {
      return false;
    }
    if (element is ConstructorElement) {
      return false;
    }
    if (name != null && element.displayName != name) {
      return false;
    }
    if (element is ExecutableElement) {
      members.add(element);
    }
    if (element is FieldElement) {
      members.add(element);
    }
    return false;
  });
  return members;
}

/// Returns a [Set] with direct subclasses of [seed].
///
/// The given [searchEngineCache] will be used or filled out as needed
/// so subsequent calls can utilize it to speed up the computation.
Future<Set<InterfaceElement>> getDirectSubClasses(
  SearchEngine searchEngine,
  InterfaceElement seed,
  SearchEngineCache searchEngineCache,
) async {
  var matches = await searchEngine.searchSubtypes(seed, searchEngineCache);
  return matches.map((match) => match.element).cast<InterfaceElement>().toSet();
}

/// Return the non-synthetic children of the given [extension]. This includes
/// fields, accessors and methods, but excludes synthetic elements.
List<Element> getExtensionMembers(ExtensionElement extension, [String? name]) {
  var members = <Element>[];
  visitChildren(extension, (element) {
    if (element.isSynthetic) {
      return false;
    }
    if (name != null && element.displayName != name) {
      return false;
    }
    if (element is ExecutableElement) {
      members.add(element);
    }
    if (element is FieldElement) {
      members.add(element);
    }
    return false;
  });
  return members;
}

/// Returns all implementations of the given [member], including in its
/// superclasses and their subclasses.
Future<Set<Element>> getHierarchyMembers(
  SearchEngine searchEngine,
  Element member, {
  OperationPerformanceImpl? performance,
}) async {
  var (members, _) = await getHierarchyMembersAndParameters(
    searchEngine,
    member,
    performance: performance,
  );
  return members;
}

/// Returns all implementations of the given [member2], including in its
/// superclasses and their subclasses.
///
/// If [includeParametersForFields] is true and [member2] is a [FieldElement],
/// any [FieldFormalParameterElement]s for the member will also be provided
/// (otherwise, the parameter set will be empty in the result).
Future<(Set<Element>, Set<FormalParameterElement>)>
getHierarchyMembersAndParameters(
  SearchEngine searchEngine,
  Element member2, {
  OperationPerformanceImpl? performance,
  bool includeParametersForFields = false,
}) async {
  performance ??= OperationPerformanceImpl('<root>');
  var members = <Element>{};
  var parameters = <FormalParameterElement>{};
  // extension member
  var enclosingElement = member2.enclosingElement;
  if (enclosingElement is ExtensionElement) {
    members.add(member2);
    return (members, parameters);
  }
  // static elements
  switch (member2) {
    case ConstructorElement():
    case FieldElement(isStatic: true):
    case MethodElement(isStatic: true):
      members.add(member2);
      return (members, parameters);
  }
  // method, field, etc
  if (enclosingElement is InterfaceElement) {
    var name = member2.displayName;

    var superElementsToSearch =
        enclosingElement.allSupertypes
            .map((superType) => superType.element)
            .where((interface) {
              return member2.isPublic || interface.library == member2.library;
            })
            .toList();
    var searchClasses = [...superElementsToSearch, enclosingElement];
    var subClasses = <InterfaceElement>{};
    for (var superClass in searchClasses) {
      // ignore if super- class does not declare member
      if (getClassMembers(superClass, name).isEmpty) {
        continue;
      }
      // check all sub- classes
      await performance.runAsync(
        'appendAllSubtypes',
        (performance) =>
            searchEngine.appendAllSubtypes(superClass, subClasses, performance),
      );
      subClasses.add(superClass);
    }
    if (member2.isPrivate) {
      subClasses.removeWhere(
        (subClass) => subClass.library != member2.library,
      );
    }
    for (var subClass in subClasses) {
      var subClassMembers = getChildren(subClass, name);
      for (var member in subClassMembers) {
        switch (member) {
          case ConstructorElement():
            members.add(member);
          case FieldElement():
            members.add(member);
          case MethodElement():
            members.add(member);
        }
      }

      if (includeParametersForFields && member2 is FieldElement) {
        for (var constructor in subClass.constructors) {
          for (var parameter in constructor.formalParameters) {
            if (parameter is FieldFormalParameterElement &&
                parameter.field2 == member2) {
              parameters.add(parameter);
            }
          }
        }
      }
    }
    return (members, parameters);
  }

  return (members, parameters);
}

/// If the [element] is a named parameter in a [MethodElement], return all
/// corresponding named parameters in the method hierarchy.
Future<List<FormalParameterElement>> getHierarchyNamedParameters(
  SearchEngine searchEngine,
  FormalParameterElement element,
) async {
  if (element.isNamed) {
    var method = element.enclosingElement;
    if (method is MethodElement) {
      var hierarchyParameters = <FormalParameterElement>[];
      var hierarchyMembers = await getHierarchyMembers(searchEngine, method);
      for (var hierarchyMethod in hierarchyMembers) {
        if (hierarchyMethod is MethodElement) {
          for (var hierarchyParameter in hierarchyMethod.formalParameters) {
            if (hierarchyParameter.isNamed &&
                hierarchyParameter.name3 == element.name3) {
              hierarchyParameters.add(hierarchyParameter);
              break;
            }
          }
        }
      }
      return hierarchyParameters;
    }
  }
  return [element];
}

Future<List<FormalParameterElement>> getHierarchyPositionalParameters(
  SearchEngine searchEngine,
  FormalParameterElement element,
) async {
  if (element.isPositional) {
    var method = element.enclosingElement;
    if (method is MethodElement) {
      var index = method.parameterIndex(element);
      // Should not ever happen but this means we can't find the index.
      if (index == null) {
        return [element];
      }
      var hierarchyParameters = <FormalParameterElement>[];
      var hierarchyMembers = await getHierarchyMembers(searchEngine, method);
      for (var hierarchyMethod in hierarchyMembers) {
        if (hierarchyMethod is MethodElement) {
          for (var hierarchyParameter in hierarchyMethod.formalParameters) {
            if (hierarchyParameter.isPositional &&
                hierarchyMethod.parameterIndex(hierarchyParameter) == index) {
              hierarchyParameters.add(hierarchyParameter);
              break;
            }
          }
        }
      }
      return hierarchyParameters;
    }
  }
  return [element];
}

/// Returns non-synthetic members of the given [InterfaceElement] and its super
/// classes.
///
/// Includes: fields, accessors and methods.
///
/// Excludes: constructors and synthetic elements.
List<Element> getMembers(InterfaceElement clazz) {
  var classElements = [...clazz.allSupertypes.map((e) => e.element), clazz];
  var members = <Element>[];
  for (var superClass in classElements) {
    members.addAll(getClassMembers(superClass));
  }
  return members;
}

/// If the given [element] is a synthetic [PropertyAccessorElement] returns
/// its variable, otherwise returns [element].
Element getSyntheticAccessorVariable(Element element) {
  if (element is PropertyAccessorElement) {
    if (element.isSynthetic) {
      return element.variable3 ?? element;
    }
  }
  return element;
}

extension on MethodElement {
  int? parameterIndex(FormalParameterElement parameter) {
    var index = 0;
    for (var positionalParameter in formalParameters.where(
      (p) => p.isPositional,
    )) {
      if (positionalParameter == parameter) {
        return index;
      }
      index++;
    }
    return null;
  }
}
