// Copyright (c) 2018, 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:test/test.dart';

import 'function_ast_visitor.dart';

class FindElement {
  final CompilationUnit unit;

  FindElement(this.unit);

  CompilationUnitElement get unitElement => unit.declaredElement;

  ClassElement class_(String name) {
    for (var class_ in unitElement.types) {
      if (class_.name == name) {
        return class_;
      }
    }
    fail('Not found class: $name');
  }

  ConstructorElement constructor(String name, {String className}) {
    assert(name != '');
    ConstructorElement result;
    for (var class_ in unitElement.types) {
      if (className == null || class_.name == className) {
        for (var constructor in class_.constructors) {
          if (constructor.name == name) {
            if (result != null) {
              throw new StateError('Not constructor name: $name');
            }
            result = constructor;
          }
        }
      }
    }
    if (result != null) {
      return result;
    }
    fail('Not found constructor: $name');
  }

  ClassElement enum_(String name) {
    for (var enum_ in unitElement.enums) {
      if (enum_.name == name) {
        return enum_;
      }
    }
    fail('Not found enum: $name');
  }

  ExportElement export(String targetUri) {
    ExportElement exportElement;
    for (var export in unitElement.library.exports) {
      var exportedUri = export.exportedLibrary.source.uri.toString();
      if (exportedUri == targetUri) {
        if (exportElement != null) {
          throw new StateError('Not unique $targetUri export.');
        }
        exportElement = export;
      }
    }
    if (exportElement != null) {
      return exportElement;
    }
    fail('Not found export: $targetUri');
  }

  FieldElement field(String name) {
    for (var type in unitElement.mixins) {
      for (var field in type.fields) {
        if (field.name == name) {
          return field;
        }
      }
    }
    for (var type in unitElement.types) {
      for (var field in type.fields) {
        if (field.name == name) {
          return field;
        }
      }
    }
    fail('Not found class field: $name');
  }

  FunctionElement function(String name) {
    for (var function in unitElement.functions) {
      if (function.name == name) {
        return function;
      }
    }
    fail('Not found top-level function: $name');
  }

  GenericTypeAliasElement genericTypeAlias(String name) {
    for (var element in unitElement.functionTypeAliases) {
      if (element is GenericTypeAliasElement && element.name == name) {
        return element;
      }
    }
    fail('Not found generic type alias: $name');
  }

  PropertyAccessorElement getter(String name, {String className}) {
    for (var class_ in unitElement.types) {
      if (className != null && class_.name != className) {
        continue;
      }
      for (var accessor in class_.accessors) {
        if (accessor.isGetter && accessor.displayName == name) {
          return accessor;
        }
      }
    }
    fail('Not found class accessor: $name');
  }

  ImportElement import(String targetUri) {
    ImportElement importElement;
    for (var import in unitElement.library.imports) {
      var importedUri = import.importedLibrary.source.uri.toString();
      if (importedUri == targetUri) {
        if (importElement != null) {
          throw new StateError('Not unique $targetUri import.');
        }
        importElement = import;
      }
    }
    if (importElement != null) {
      return importElement;
    }
    fail('Not found import: $targetUri');
  }

  InterfaceType interfaceType(String name) {
    return class_(name).type;
  }

  LocalVariableElement localVar(String name) {
    LocalVariableElement result;
    unit.accept(new FunctionAstVisitor(
      variableDeclaration: (node) {
        var element = node.declaredElement;
        if (element is LocalVariableElement) {
          if (result != null) {
            throw new StateError('Local variable name $name is not unique.');
          }
          result = element;
        }
      },
    ));
    if (result == null) {
      fail('Not found local variable: $name');
    }
    return result;
  }

  MethodElement method(String name, {String of}) {
    MethodElement result;

    void findIn(List<MethodElement> methods) {
      for (var method in methods) {
        if (method.name == name) {
          if (result != null) {
            throw new StateError('Method name $name is not unique.');
          }
          result = method;
        }
      }
    }

    for (var class_ in unitElement.types) {
      if (of != null && class_.name != of) {
        continue;
      }
      findIn(class_.methods);
    }

    for (var mixin in unitElement.mixins) {
      if (of != null && mixin.name != of) {
        continue;
      }
      findIn(mixin.methods);
    }

    if (result != null) {
      return result;
    }
    fail('Not found class method: $name');
  }

  ClassElement mixin(String name) {
    for (var mixin in unitElement.mixins) {
      if (mixin.name == name) {
        return mixin;
      }
    }
    fail('Not found mixin: $name');
  }

  ParameterElement parameter(String name) {
    ParameterElement parameterElement;
    void considerParameter(ParameterElement parameter) {
      if (parameter.name == name) {
        if (parameterElement != null) {
          throw new StateError('Parameter name $name is not unique.');
        }
        parameterElement = parameter;
      }
    }

    for (var accessor in unitElement.accessors) {
      accessor.parameters.forEach(considerParameter);
    }
    for (var function in unitElement.functions) {
      function.parameters.forEach(considerParameter);
    }
    for (var function in unitElement.functionTypeAliases) {
      function.parameters.forEach(considerParameter);
    }
    for (var class_ in unitElement.types) {
      for (var constructor in class_.constructors) {
        constructor.parameters.forEach(considerParameter);
      }
      for (var method in class_.methods) {
        method.parameters.forEach(considerParameter);
      }
    }
    if (parameterElement != null) {
      return parameterElement;
    }
    fail('No parameter found with name $name');
  }

  PrefixElement prefix(String name) {
    for (var import_ in unitElement.library.imports) {
      var prefix = import_.prefix;
      if (prefix != null && prefix.name == name) {
        return prefix;
      }
    }
    fail('Prefix not found: $name');
  }

  PropertyAccessorElement setter(String name, {String className}) {
    PropertyAccessorElement result;
    for (var class_ in unitElement.types) {
      if (className != null && class_.name != className) {
        continue;
      }
      for (var accessor in class_.accessors) {
        if (accessor.isSetter && accessor.displayName == name) {
          if (result == null) {
            result = accessor;
          } else {
            throw new StateError('Class setter $name is not unique.');
          }
        }
      }
    }
    if (result == null) {
      fail('Not found class setter: $name');
    }
    return result;
  }

  FunctionElement topFunction(String name) {
    for (var function in unitElement.functions) {
      if (function.name == name) {
        return function;
      }
    }
    fail('Not found top-level function: $name');
  }

  PropertyAccessorElement topGet(String name) {
    return topVar(name).getter;
  }

  PropertyAccessorElement topSet(String name) {
    return topVar(name).setter;
  }

  TopLevelVariableElement topVar(String name) {
    for (var variable in unitElement.topLevelVariables) {
      if (variable.name == name) {
        return variable;
      }
    }
    fail('Not found top-level variable: $name');
  }

  TypeParameterElement typeParameter(String name) {
    TypeParameterElement result;

    void consider(TypeParameterElement candidate) {
      if (candidate.name == name) {
        if (result != null) {
          throw new StateError('Type parameter $name is not unique.');
        }
        result = candidate;
      }
    }

    for (var type in unitElement.functionTypeAliases) {
      type.typeParameters.forEach(consider);
    }
    for (var type in unitElement.types) {
      type.typeParameters.forEach(consider);
    }
    if (result != null) {
      return result;
    }
    fail('Not found type parameter: $name');
  }

  ConstructorElement unnamedConstructor(String name) {
    return class_(name).unnamedConstructor;
  }
}
