// Copyright (c) 2013, 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:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/testing/element_search.dart';
import 'package:test/test.dart';

/**
 * Search the [unit] for the [LocalVariableElement] with the given [name].
 * Fail if there is not exactly one such variable.
 */
FunctionElement findLocalFunction(CompilationUnit unit, String name) {
  List<Element> elements = findElementsByName(unit, name);
  List<Element> functions =
      elements.where((e) => e is FunctionElement).toList();
  expect(functions, hasLength(1));
  return functions[0];
}

/**
 * Search the [unit] for the [LocalVariableElement] with the given [name].
 * Fail if there is not exactly one such variable.
 */
LocalVariableElement findLocalVariable(CompilationUnit unit, String name) {
  List<Element> elements = findElementsByName(unit, name);
  List<Element> localVariables =
      elements.where((e) => e is LocalVariableElement).toList();
  expect(localVariables, hasLength(1));
  return localVariables[0];
}

/**
 * The type of an assertion which asserts properties of [T]s.
 */
typedef void Asserter<T>(T type);

/**
 * The type of a function which given an [S], builds an assertion over [T]s.
 */
typedef Asserter<T> AsserterBuilder<S, T>(S arg);

/**
 * The type of a function which given an [S0] and an S1, builds an assertion
 * over [T]s.
 */
typedef Asserter<T> AsserterBuilder2<S0, S1, T>(S0 arg0, S1 arg1);

/**
 * The type of a function which given an [R] returns an [AsserterBuilder] over
 * [S]s and [T]s.  That is, it returns a function which given an [S], returns
 * a function over [T]s.
 */
typedef AsserterBuilder<S, T> AsserterBuilderBuilder<R, S, T>(R arg);

class AstFinder {
  /**
   * Return the declaration of the class with the given [className] in the given
   * compilation [unit].
   */
  static ClassDeclaration getClass(CompilationUnit unit, String className) {
    NodeList<CompilationUnitMember> unitMembers = unit.declarations;
    for (CompilationUnitMember unitMember in unitMembers) {
      if (unitMember is ClassDeclaration && unitMember.name.name == className) {
        return unitMember;
      }
    }
    Source source = unit.declaredElement.source;
    fail('No class named $className in $source');
  }

  /**
   * Return the declaration of the constructor with the given [constructorName] in
   * the class with the given [className] in the given compilation [unit].  If
   * constructorName is null, return the default constructor;
   */
  static ConstructorDeclaration getConstructorInClass(
      CompilationUnit unit, String className, String constructorName) {
    ClassDeclaration unitMember = getClass(unit, className);
    NodeList<ClassMember> classMembers = unitMember.members;
    for (ClassMember classMember in classMembers) {
      if (classMember is ConstructorDeclaration) {
        if (classMember.name?.name == constructorName) {
          return classMember;
        }
      }
    }
    fail('No constructor named $constructorName in $className');
  }

  /**
   * Return the declaration of the field with the given [fieldName] in the class
   * with the given [className] in the given compilation [unit].
   */
  static VariableDeclaration getFieldInClass(
      CompilationUnit unit, String className, String fieldName) {
    ClassDeclaration unitMember = getClass(unit, className);
    NodeList<ClassMember> classMembers = unitMember.members;
    for (ClassMember classMember in classMembers) {
      if (classMember is FieldDeclaration) {
        NodeList<VariableDeclaration> fields = classMember.fields.variables;
        for (VariableDeclaration field in fields) {
          if (field.name.name == fieldName) {
            return field;
          }
        }
      }
    }
    fail('No field named $fieldName in $className');
  }

  /**
   * Return the element of the field with the given [fieldName] in the class
   * with the given [className] in the given compilation [unit].
   */
  static FieldElement getFieldInClassElement(
      CompilationUnit unit, String className, String fieldName) {
    return getFieldInClass(unit, className, fieldName)?.name?.staticElement;
  }

  /**
   * Return the declaration of the method with the given [methodName] in the
   * class with the given [className] in the given compilation [unit].
   */
  static MethodDeclaration getMethodInClass(
      CompilationUnit unit, String className, String methodName) {
    ClassDeclaration unitMember = getClass(unit, className);
    NodeList<ClassMember> classMembers = unitMember.members;
    for (ClassMember classMember in classMembers) {
      if (classMember is MethodDeclaration) {
        if (classMember.name.name == methodName) {
          return classMember;
        }
      }
    }
    fail('No method named $methodName in $className');
  }

  /**
   * Return the statements in the body of a the method with the given
   * [methodName] in the class with the given [className] in the given
   * compilation [unit].
   */
  static List<Statement> getStatementsInMethod(
      CompilationUnit unit, String className, String methodName) {
    MethodDeclaration method = getMethodInClass(unit, className, methodName);
    BlockFunctionBody body = method.body;
    return body.block.statements;
  }

  /**
   * Return the statements in the body of the top-level function with the given
   * [functionName] in the given compilation [unit].
   */
  static List<Statement> getStatementsInTopLevelFunction(
      CompilationUnit unit, String functionName) {
    FunctionDeclaration function = getTopLevelFunction(unit, functionName);
    BlockFunctionBody body = function.functionExpression.body;
    return body.block.statements;
  }

  /**
   * Return the declaration of the top-level function with the given
   * [functionName] in the given compilation [unit].
   */
  static FunctionDeclaration getTopLevelFunction(
      CompilationUnit unit, String functionName) {
    NodeList<CompilationUnitMember> unitMembers = unit.declarations;
    for (CompilationUnitMember unitMember in unitMembers) {
      if (unitMember is FunctionDeclaration) {
        if (unitMember.name.name == functionName) {
          return unitMember;
        }
      }
    }
    fail('No toplevel function named $functionName found');
  }

  /**
   * Return the declaration of the top-level variable with the given
   * [variableName] in the given compilation [unit].
   */
  static VariableDeclaration getTopLevelVariable(
      CompilationUnit unit, String variableName) {
    NodeList<CompilationUnitMember> unitMembers = unit.declarations;
    for (CompilationUnitMember unitMember in unitMembers) {
      if (unitMember is TopLevelVariableDeclaration) {
        NodeList<VariableDeclaration> variables =
            unitMember.variables.variables;
        for (VariableDeclaration variable in variables) {
          if (variable.name.name == variableName) {
            return variable;
          }
        }
      }
    }
    fail('No toplevel variable named $variableName found');
  }

  /**
   * Return the top-level variable element with the given [name].
   */
  static TopLevelVariableElement getTopLevelVariableElement(
      CompilationUnit unit, String name) {
    return getTopLevelVariable(unit, name)?.name?.staticElement;
  }
}

/**
 * Class for compositionally building up assertions on types
 */
class TypeAssertions {
  // TODO(leafp): Make these matchers.
  // https://pub.dev/documentation/matcher/latest/matcher/Matcher-class.html

  /**
   * Provides primitive types for basic type assertions.
   */
  final TypeProvider _typeProvider;

  TypeAssertions(this._typeProvider);

  /**
   * Primitive assertion for the dynamic type
   */
  Asserter<DartType> get isDynamic => isType(_typeProvider.dynamicType);

  /**
   * Primitive assertion for the int type
   */
  Asserter<DartType> get isInt => isType(_typeProvider.intType);

  /**
   * Primitive assertion for the list type
   */
  Asserter<DartType> get isList => hasElement(_typeProvider.listElement);

  /**
   * Primitive assertion for the map type
   */
  Asserter<DartType> get isMap => hasElement(_typeProvider.mapElement);

  /**
   * Primitive assertion for the Null type
   */
  Asserter<DartType> get isNull => isType(_typeProvider.nullType);

  /**
   * Primitive assertion for the num type
   */
  Asserter<DartType> get isNum => isType(_typeProvider.numType);

  /**
   * Primitive assertion for the Object type
   */
  Asserter<DartType> get isObject => isType(_typeProvider.objectType);

  /**
   * Primitive assertion for the string type
   */
  Asserter<DartType> get isString => isType(_typeProvider.stringType);

  /**
   * Assert that a type has the element that is equal to the [expected].
   */
  Asserter<DartType> hasElement(Element expected) =>
      (DartType type) => expect(expected, type.element);

  /**
   * Given assertions for the argument and return types, produce an
   *  assertion over unary function types.
   */
  Asserter<DartType> isFunction2Of(
          Asserter<DartType> argType, Asserter<DartType> returnType) =>
      (DartType type) {
        FunctionType fType = (type as FunctionType);
        argType(fType.normalParameterTypes[0]);
        returnType(fType.returnType);
      };

  /**
   * Given an assertion for the base type and assertions over the type
   * parameters, produce an assertion over instantiations.
   */
  AsserterBuilder<List<Asserter<DartType>>, DartType> isInstantiationOf(
          Asserter<DartType> baseAssert) =>
      (List<Asserter<DartType>> argAsserts) => (DartType type) {
            InterfaceType t = (type as InterfaceType);
            baseAssert(t);
            List<DartType> typeArguments = t.typeArguments;
            expect(typeArguments, hasLength(argAsserts.length));
            for (int i = 0; i < typeArguments.length; i++) {
              argAsserts[i](typeArguments[i]);
            }
          };

  /**
   * Assert that a type is the List type, and that the given assertion holds
   * over the type parameter.
   */
  Asserter<InterfaceType> isListOf(Asserter<DartType> argAssert) =>
      isInstantiationOf(isList)([argAssert]);

  /**
   * Assert that a type is the Map type, and that the given assertions hold
   * over the type parameters.
   */
  Asserter<InterfaceType> isMapOf(
          Asserter<DartType> argAssert0, Asserter<DartType> argAssert1) =>
      isInstantiationOf(isMap)([argAssert0, argAssert1]);

  /**
   * Assert that a type is equal to the [expected].
   */
  Asserter<DartType> isType(DartType expected) => (DartType t) {
        expect(t, expected);
      };
}
