// 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.

// This code was auto-generated, is not intended to be edited, and is subject to
// significant change. Please see the README file for more information.

library test.services.src.search.search_engine;

import 'dart:async';

import 'package:analysis_services/index/index.dart';
import 'package:analysis_services/index/local_memory_index.dart';
import 'package:analysis_services/search/search_engine.dart';
import 'package:analysis_services/src/search/search_engine.dart';
import 'package:analysis_testing/abstract_single_unit.dart';
import 'package:analysis_testing/mocks.dart';
import 'package:analysis_testing/reflective_tests.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:typed_mock/typed_mock.dart';
import 'package:unittest/unittest.dart';


main() {
  groupSep = ' | ';
  runReflectiveTests(SearchEngineImplTest);
}

class ExpectedMatch {
  final Element element;
  final MatchKind kind;
  SourceRange range;
  final bool isResolved;
  final bool isQualified;

  ExpectedMatch(this.element, this.kind, int offset, int length,
      {this.isResolved: true, this.isQualified: false}) {
    this.range = new SourceRange(offset, length);
  }

  bool operator ==(SearchMatch match) {
    return match.element == this.element &&
        match.kind == this.kind &&
        match.isResolved == this.isResolved &&
        match.isQualified == this.isQualified &&
        match.sourceRange == this.range;
  }

  @override
  String toString() {
    StringBuffer buffer = new StringBuffer();
    buffer.write("ExpectedMatch(kind=");
    buffer.write(kind);
    buffer.write(", element=");
    buffer.write(element != null ? element.displayName : 'null');
    buffer.write(", range=");
    buffer.write(range);
    buffer.write(", isResolved=");
    buffer.write(isResolved);
    buffer.write(", isQualified=");
    buffer.write(isQualified);
    buffer.write(")");
    return buffer.toString();
  }
}


class MockAngularComponentElement extends TypedMock implements
    AngularComponentElement {
  final kind = ElementKind.ANGULAR_COMPONENT;
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}


class MockAngularControllerElement extends TypedMock implements
    AngularControllerElement {
  final kind = ElementKind.ANGULAR_CONTROLLER;
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}


class MockAngularFormatterElement extends TypedMock implements
    AngularFormatterElement {
  final kind = ElementKind.ANGULAR_FORMATTER;
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}


class MockIndex extends TypedMock implements Index {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}


@ReflectiveTestCase()
class SearchEngineImplTest extends AbstractSingleUnitTest {
  Index index;
  SearchEngineImpl searchEngine;

//  void mockLocation(Element element, Relationship relationship,
//      Location location) {
//    mockLocations(element, relationship, [location]);
//  }
//
//  void mockLocations(Element element, Relationship relationship,
//      List<Location> locations) {
//    index.getRelationships(element, relationship);
//    when(null).thenReturn(new Future.value(locations));
//  }

  void setUp() {
    super.setUp();
    index = createLocalMemoryIndex();
    searchEngine = new SearchEngineImpl(index);
  }

  Future test_searchMemberDeclarations() {
    _indexTestUnit('''
class A {
  test() {}
}
class B {
  int test = 42;
}
''');
    NameElement element = new NameElement('test');
    ClassElement elementA = findElement('A');
    ClassElement elementB = findElement('B');
    var expected = [
        _expectId(elementA.methods[0], MatchKind.DECLARATION, 'test() {}'),
        _expectId(elementB.fields[0], MatchKind.DECLARATION, 'test = 42;')];
    return searchEngine.searchMemberDeclarations('test').then((matches) {
      _assertMatches(matches, expected);
    });
  }

  Future test_searchMemberReferences() {
    _indexTestUnit('''
class A {
  var test; // A
  mainA() {
    test(); // a-inv-r-nq
    test = 1; // a-write-r-nq
    test += 2; // a-read-write-r-nq
    print(test); // a-read-r-nq
  }
}
main(A a, p) {
  a.test(); // a-inv-r-q
  a.test = 1; // a-write-r-q
  a.test += 2; // a-read-write-r-q
  print(a.test); // a-read-r-q
  p.test(); // p-inv-ur-q
  p.test = 1; // p-write-ur-q
  p.test += 2; // p-read-write-ur-q
  print(p.test); // p-read-ur-q
}
''');
    ClassElement elementA = findElement('A');
    ClassElement elementB = findElement('B');
    Element mainA = findElement('mainA');
    Element main = findElement('main');
    var expected = [
        _expectId(mainA, MatchKind.INVOCATION, 'test(); // a-inv-r-nq'),
        _expectId(mainA, MatchKind.WRITE, 'test = 1; // a-write-r-nq'),
        _expectId(mainA, MatchKind.READ_WRITE, 'test += 2; // a-read-write-r-nq'),
        _expectId(mainA, MatchKind.READ, 'test); // a-read-r-nq'),
        _expectIdQ(main, MatchKind.INVOCATION, 'test(); // a-inv-r-q'),
        _expectIdQ(main, MatchKind.WRITE, 'test = 1; // a-write-r-q'),
        _expectIdQ(main, MatchKind.READ_WRITE, 'test += 2; // a-read-write-r-q'),
        _expectIdQ(main, MatchKind.READ, 'test); // a-read-r-q'),
        _expectIdU(main, MatchKind.INVOCATION, 'test(); // p-inv-ur-q'),
        _expectIdU(main, MatchKind.WRITE, 'test = 1; // p-write-ur-q'),
        _expectIdU(main, MatchKind.READ_WRITE, 'test += 2; // p-read-write-ur-q'),
        _expectIdU(main, MatchKind.READ, 'test); // p-read-ur-q'),];
    return searchEngine.searchMemberReferences('test').then((matches) {
      _assertMatches(matches, expected);
    });
  }

  Future test_searchReferences_AngularComponentElement() {
    // use mocks
    index = new MockIndex();
    searchEngine = new SearchEngineImpl(index);
    Element elementA = new MockElement('A');
    Element elementB = new MockElement('B');
    // fill mocks
    AngularComponentElement element = new MockAngularComponentElement();
    void mockLocation(Element element, Relationship relationship,
        Location location) {
      index.getRelationships(element, relationship);
      when(null).thenReturn(new Future.value([location]));
    }
    mockLocation(
        element,
        IndexConstants.ANGULAR_REFERENCE,
        new Location(elementA, 1, 10));
    mockLocation(
        element,
        IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE,
        new Location(elementB, 2, 20));
    var expected = [
        new ExpectedMatch(elementA, MatchKind.ANGULAR_REFERENCE, 1, 10),
        new ExpectedMatch(elementB, MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, 2, 20)];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_ClassElement() {
    _indexTestUnit('''
class A {}
main(A p) {
  A v;
}
''');
    ClassElement element = findElement('A');
    Element pElement = findElement('p');
    Element vElement = findElement('v');
    var expected = [
        _expectId(pElement, MatchKind.REFERENCE, 'A p'),
        _expectId(vElement, MatchKind.REFERENCE, 'A v')];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_CompilationUnitElement() {
    addSource('/my_part.dart', '''
part of lib;
''');
    _indexTestUnit('''
library lib;
part 'my_part.dart';
''');
    CompilationUnitElement element = testLibraryElement.parts[0];
    var expected = [
        _expectId(
            testUnitElement,
            MatchKind.REFERENCE,
            "'my_part.dart'",
            length: "'my_part.dart'".length)];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_ConstructorElement() {
    _indexTestUnit('''
class A {
  A.named() {}
}
main() {
  new A.named();
}
''');
    ConstructorElement element = findElement('named');
    ClassElement elementA = findElement('A');
    Element mainElement = findElement('main');
    var expected = [
        _expectId(elementA, MatchKind.DECLARATION, '.named() {}', length: 6),
        _expectId(mainElement, MatchKind.REFERENCE, '.named();', length: 6)];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_Element_unknown() {
    return _verifyReferences(UniverseElement.INSTANCE, []);
  }

  Future test_searchReferences_FieldElement() {
    _indexTestUnit('''
class A {
  var field;
  A({this.field});
  main() {
    new A(field: 1);
    // getter
    print(field); // ref-nq
    print(this.field); // ref-q
    field(); // inv-nq
    this.field(); // inv-q
    // setter
    field = 2; // ref-nq;
    this.field = 3; // ref-q;
  }
}
''');
    FieldElement element = findElement('field');
    Element main = findElement('main');
    Element fieldParameter = findElement('field', ElementKind.PARAMETER);
    var expected = [
        _expectId(fieldParameter, MatchKind.REFERENCE, 'field}'),
        _expectId(main, MatchKind.REFERENCE, 'field: 1'),
        _expectId(main, MatchKind.READ, 'field); // ref-nq'),
        _expectIdQ(main, MatchKind.READ, 'field); // ref-q'),
        _expectId(main, MatchKind.INVOCATION, 'field(); // inv-nq'),
        _expectIdQ(main, MatchKind.INVOCATION, 'field(); // inv-q'),
        _expectId(main, MatchKind.WRITE, 'field = 2; // ref-nq'),
        _expectIdQ(main, MatchKind.WRITE, 'field = 3; // ref-q'),
        ];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_FunctionElement() {
    _indexTestUnit('''
test() {}
main() {
  test();
  print(test);
}
''');
    FunctionElement element = findElement('test');
    Element mainElement = findElement('main');
    var expected = [
        _expectId(mainElement, MatchKind.INVOCATION, 'test();'),
        _expectId(mainElement, MatchKind.REFERENCE, 'test);')];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_FunctionTypeAliasElement() {
    _indexTestUnit('''
typedef Test();
main() {
  Test a;
  Test b;
}
''');
    FunctionTypeAliasElement element = findElement('Test');
    Element aElement = findElement('a');
    Element bElement = findElement('b');
    var expected = [
        _expectId(aElement, MatchKind.REFERENCE, 'Test a;'),
        _expectId(bElement, MatchKind.REFERENCE, 'Test b;')];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_ImportElement_noPrefix() {
    _indexTestUnit('''
import 'dart:math';
main() {
  print(E);
}
''');
    ImportElement element = testLibraryElement.imports[0];
    Element mainElement = findElement('main');
    var kind = MatchKind.REFERENCE;
    var expected = [_expectId(mainElement, kind, 'E);', length: 0)];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_ImportElement_withPrefix() {
    _indexTestUnit('''
import 'dart:math' as math;
main() {
  print(math.PI);
}
''');
    ImportElement element = testLibraryElement.imports[0];
    Element mainElement = findElement('main');
    var kind = MatchKind.REFERENCE;
    var expected = [
        _expectId(mainElement, kind, 'math.PI);', length: 'math.'.length)];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_LibraryElement() {
    var codeA = 'part of lib; // A';
    var codeB = 'part of lib; // B';
    var sourceA = addSource('/unitA.dart', codeA);
    var sourceB = addSource('/unitB.dart', codeB);
    _indexTestUnit('''
library lib;
part 'unitA.dart';
part 'unitB.dart';
''');
    LibraryElement element = testLibraryElement;
    CompilationUnitElement elementA = element.parts[0];
    CompilationUnitElement elementB = element.parts[1];
    index.indexUnit(context, elementA.node);
    index.indexUnit(context, elementB.node);
    Element mainElement = findElement('main');
    var expected = [
        new ExpectedMatch(
            elementA,
            MatchKind.REFERENCE,
            codeA.indexOf('lib; // A'),
            'lib'.length),
        new ExpectedMatch(
            elementB,
            MatchKind.REFERENCE,
            codeB.indexOf('lib; // B'),
            'lib'.length),];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_LocalVariableElement() {
    _indexTestUnit('''
main() {
  var v;
  v = 1;
  v += 2;
  print(v);
  v();
}
''');
    LocalVariableElement element = findElement('v');
    Element mainElement = findElement('main');
    var expected = [
        _expectId(mainElement, MatchKind.WRITE, 'v = 1;'),
        _expectId(mainElement, MatchKind.READ_WRITE, 'v += 2;'),
        _expectId(mainElement, MatchKind.READ, 'v);'),
        _expectId(mainElement, MatchKind.INVOCATION, 'v();')];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_MethodElement() {
    _indexTestUnit('''
class A {
  m() {}
  main() {
    m(); // 1
    this.m(); // 2
    print(m); // 3
    print(this.m); // 4
  }
}
''');
    MethodElement method = findElement('m');
    Element mainElement = findElement('main');
    var expected = [
        _expectId(mainElement, MatchKind.INVOCATION, 'm(); // 1'),
        _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // 2'),
        _expectId(mainElement, MatchKind.REFERENCE, 'm); // 3'),
        _expectIdQ(mainElement, MatchKind.REFERENCE, 'm); // 4')];
    return _verifyReferences(method, expected);
  }

  Future test_searchReferences_MethodMember() {
    _indexTestUnit('''
class A<T> {
  T m() => null;
}
main(A<int> a) {
  a.m(); // ref
}
''');
    MethodMember method = findNodeElementAtString('m(); // ref');
    Element mainElement = findElement('main');
    var expected = [
        _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // ref')];
    return _verifyReferences(method, expected);
  }

  Future test_searchReferences_ParameterElement() {
    _indexTestUnit('''
foo({p}) {
  p = 1;
  p += 2;
  print(p);
  p();
}
main() {
  foo(p: 42);
}
''');
    ParameterElement element = findElement('p');
    Element fooElement = findElement('foo');
    Element mainElement = findElement('main');
    var expected = [
        _expectId(fooElement, MatchKind.WRITE, 'p = 1;'),
        _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'),
        _expectId(fooElement, MatchKind.READ, 'p);'),
        _expectId(fooElement, MatchKind.INVOCATION, 'p();'),
        _expectId(mainElement, MatchKind.REFERENCE, 'p: 42')];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_PropertyAccessorElement_getter() {
    _indexTestUnit('''
class A {
  get g => null;
  main() {
    g; // 1
    this.g; // 2
  }
}
''');
    PropertyAccessorElement element = findElement('g', ElementKind.GETTER);
    Element mainElement = findElement('main');
    var expected = [
        _expectId(mainElement, MatchKind.REFERENCE, 'g; // 1'),
        _expectIdQ(mainElement, MatchKind.REFERENCE, 'g; // 2')];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_PropertyAccessorElement_setter() {
    _indexTestUnit('''
class A {
  set s(x) {}
  main() {
    s = 1;
    this.s = 2;
  }
}
''');
    PropertyAccessorElement element = findElement('s=');
    Element mainElement = findElement('main');
    var expected = [
        _expectId(mainElement, MatchKind.REFERENCE, 's = 1'),
        _expectIdQ(mainElement, MatchKind.REFERENCE, 's = 2')];
    return _verifyReferences(element, expected);
  }

  Future test_searchReferences_TopLevelVariableElement() {
    addSource('/lib.dart', '''
library lib;
var V;
''');
    _indexTestUnit('''
import 'lib.dart' show V; // imp
import 'lib.dart' as pref;
main() {
  pref.V = 1; // q
  print(pref.V); // q
  pref.V(); // q
  V = 1; // nq
  print(V); // nq
  V(); // nq
}
''');
    ImportElement importElement = testLibraryElement.imports[0];
    CompilationUnitElement impUnit =
        importElement.importedLibrary.definingCompilationUnit;
    TopLevelVariableElement variable = impUnit.topLevelVariables[0];
    Element main = findElement('main');
    var expected = [
        _expectId(testUnitElement, MatchKind.REFERENCE, 'V; // imp'),
        _expectId(main, MatchKind.WRITE, 'V = 1; // q'),
        _expectId(main, MatchKind.READ, 'V); // q'),
        _expectId(main, MatchKind.INVOCATION, 'V(); // q'),
        _expectId(main, MatchKind.WRITE, 'V = 1; // nq'),
        _expectId(main, MatchKind.READ, 'V); // nq'),
        _expectId(main, MatchKind.INVOCATION, 'V(); // nq'),
        ];
    return _verifyReferences(variable, expected);
  }

  Future test_searchReferences_TypeParameterElement() {
    _indexTestUnit('''
class A<T> {
  main(T a, T b) {}
}
''');
    TypeParameterElement element = findElement('T');
    Element aElement = findElement('a');
    Element bElement = findElement('b');
    var expected = [
        _expectId(aElement, MatchKind.REFERENCE, 'T a'),
        _expectId(bElement, MatchKind.REFERENCE, 'T b')];
    return _verifyReferences(element, expected);
  }

  Future test_searchSubtypes() {
    _indexTestUnit('''
class T {}
class A extends T {} // A
class B = Object with T; // B
class C implements T {} // C
''');
    ClassElement element = findElement('T');
    ClassElement elementA = findElement('A');
    ClassElement elementB = findElement('B');
    ClassElement elementC = findElement('C');
    var expected = [
        _expectId(elementA, MatchKind.REFERENCE, 'T {} // A'),
        _expectId(elementB, MatchKind.REFERENCE, 'T; // B'),
        _expectId(elementC, MatchKind.REFERENCE, 'T {} // C')];
    return searchEngine.searchSubtypes(element).then((matches) {
      _assertMatches(matches, expected);
    });
  }

  Future test_searchTopLevelDeclarations() {
    _indexTestUnit('''
class A {} // A
class B = Object with A;
typedef C();
D() {}
var E = null;
class NoMatchABCDE {}
''');
    NameElement element = new NameElement('test');
    Element topA = findElement('A');
    Element topB = findElement('B');
    Element topC = findElement('C');
    Element topD = findElement('D');
    Element topE = findElement('E');
    Element topNoMatch = new MockElement('NoMatchABCDE');
    var expected = [
        _expectId(topA, MatchKind.DECLARATION, 'A {} // A'),
        _expectId(topB, MatchKind.DECLARATION, 'B ='),
        _expectId(topC, MatchKind.DECLARATION, 'C()'),
        _expectId(topD, MatchKind.DECLARATION, 'D() {}'),
        _expectId(topE, MatchKind.DECLARATION, 'E = null')];
    return _verifyTopLevelDeclarations('^[A-E]\$', expected);
  }

  ExpectedMatch _expectId(Element element, MatchKind kind, String search,
      {int length, bool isResolved: true, bool isQualified: false}) {
    int offset = findOffset(search);
    if (length == null) {
      length = getLeadingIdentifierLength(search);
    }
    return new ExpectedMatch(
        element,
        kind,
        offset,
        length,
        isResolved: isResolved,
        isQualified: isQualified);
  }

  ExpectedMatch _expectIdQ(Element element, MatchKind kind, String search) {
    return _expectId(element, kind, search, isQualified: true);
  }

  ExpectedMatch _expectIdU(Element element, MatchKind kind, String search) {
    return _expectId(
        element,
        kind,
        search,
        isQualified: true,
        isResolved: false);
  }

  void _indexTestUnit(String code) {
    resolveTestUnit(code);
    index.indexUnit(context, testUnit);
  }

  Future _verifyReferences(Element element,
      List<ExpectedMatch> expectedMatches) {
    return searchEngine.searchReferences(
        element).then((List<SearchMatch> matches) {
      _assertMatches(matches, expectedMatches);
    });
  }

  Future _verifyTopLevelDeclarations(String pattern,
      List<ExpectedMatch> expectedMatches) {
    return searchEngine.searchTopLevelDeclarations(
        pattern).then((List<SearchMatch> matches) {
      _assertMatches(matches, expectedMatches);
    });
  }

  static void _assertMatches(List<SearchMatch> matches,
      List<ExpectedMatch> expectedMatches) {
    expect(matches, unorderedEquals(expectedMatches));
  }
}
