// 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/cider/completion.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/analysis/results.dart';
import 'package:analyzer/src/test_utilities/function_ast_visitor.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
    show CompletionSuggestion, CompletionSuggestionKind, ElementKind;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'cider_service.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(CiderCompletionComputerTest);
  });
}

@reflectiveTest
class CiderCompletionComputerTest extends CiderServiceTest {
  final CiderCompletionCache _completionCache = CiderCompletionCache();

  late CiderCompletionComputer _computer;
  void Function(ResolvedForCompletionResultImpl)? _testResolvedUnit;

  late CiderCompletionResult _completionResult;
  late List<CompletionSuggestion> _suggestions;

  Future<void> test_compute() async {
    await _compute(r'''
class A {}

int a = 0;

void f(int b) {
  int c = 0;
  ^
}
''');

    _assertHasCompletion(text: 'a');
    _assertHasCompletion(text: 'b');
    _assertHasCompletion(text: 'c');
    _assertHasClass(text: 'A');
    _assertHasClass(text: 'String');

    _assertNoClass(text: 'Random');
  }

  Future<void> test_compute_performance_operations() async {
    await _compute(r'''
void f() {
  ^
}
''');

    _assertHasOperationPerformance(['resolution']);
    _assertHasOperationPerformance(['suggestions']);
    _assertHasOperationPerformance(['suggestions', 'KeywordContributor']);
  }

  Future<void> test_compute_prefixStart_beforeToken_identifier() async {
    await _compute('''
const foo = 0;

class A {
  @fo^
}
''');
    expect(_completionResult.prefixStart.line, 3);
    expect(_completionResult.prefixStart.column, 3);
  }

  Future<void> test_compute_prefixStart_beforeToken_keyword() async {
    await _compute('''
import 'dart:async' h^;
''');
    _assertHasKeyword(text: 'hide');
    _assertNoKeyword(text: 'show');
    expect(_completionResult.prefixStart.line, 0);
    expect(_completionResult.prefixStart.column, 20);
  }

  Future<void> test_compute_prefixStart_identifier() async {
    await _compute('''
class A {
  String foobar;
}

void f(A a) {
  a.foo^
}
''');
    expect(_completionResult.prefixStart.line, 5);
    expect(_completionResult.prefixStart.column, 4);
  }

  Future<void> test_compute_prefixStart_noPrefix() async {
    await _compute(r'''
import 'dart:math';
^
''');
    expect(_completionResult.prefixStart.line, 1);
    expect(_completionResult.prefixStart.column, 0);
  }

  Future<void> test_compute_updateImportedLibrary() async {
    var aPath = convertPath('/workspace/dart/test/lib/a.dart');
    newFile(aPath, r'''
class A {}
''');

    var content = r'''
import 'a.dart';
^
''';

    await _compute(content);
    _assertComputedImportedLibraries([aPath], hasCore: true);
    _assertHasClass(text: 'A');

    // Repeat the query, still has 'A'.
    _createFileResolver();
    await _compute(content);
    _assertComputedImportedLibraries([]);
    _assertHasClass(text: 'A');

    // Update the imported library, has 'B', but not 'A'.
    newFile(aPath, r'''
class B {}
''');
    _createFileResolver();
    await _compute(content);
    _assertComputedImportedLibraries([aPath]);
    _assertHasClass(text: 'B');
    _assertNoClass(text: 'A');
  }

  Future<void> test_compute_updateImports() async {
    var aPath = convertPath('/workspace/dart/test/lib/a.dart');
    newFile(aPath, r'''
class A {}
''');

    await _compute(r'''
var a = ^;
''');
    _assertComputedImportedLibraries([], hasCore: true);
    _assertHasClass(text: 'String');

    // Repeat the query, still has 'A'.
    _createFileResolver();
    await _compute(r'''
import 'a.dart';
var a = ^;
''');
    _assertComputedImportedLibraries([aPath]);
    _assertHasClass(text: 'A');
    _assertHasClass(text: 'String');
  }

  Future<void> test_compute_uriContributor_disabled() async {
    newFile('/workspace/dart/test/lib/a.dart', '');
    await _compute(r'''
import '^';
''');
    expect(_suggestions, isEmpty);
  }

  Future<void> test_filterSort_byPattern_excludeNotMatching() async {
    await _compute(r'''
var a = F^;
''');

    _assertHasClass(text: 'Future');
    _assertNoClass(text: 'String');
  }

  Future<void> test_filterSort_byPattern_location_beforeMethod() async {
    await _compute(r'''
class A {
  F^
  void foo() {}
}
''');

    _assertHasClass(text: 'Future');
    _assertNoClass(text: 'String');
  }

  Future<void> test_filterSort_byPattern_location_functionReturnType() async {
    await _compute(r'''
F^ foo() {}
''');

    _assertHasClass(text: 'Future');
    _assertNoClass(text: 'String');
  }

  Future<void> test_filterSort_byPattern_location_methodReturnType() async {
    await _compute(r'''
class A {
  F^ foo() {}
}
''');

    _assertHasClass(text: 'Future');
    _assertNoClass(text: 'String');
  }

  Future<void> test_filterSort_byPattern_location_parameterType() async {
    await _compute(r'''
void foo(F^ a) {}
''');

    _assertHasClass(text: 'Future');
    _assertNoClass(text: 'String');
  }

  Future<void> test_filterSort_byPattern_location_parameterType2() async {
    await _compute(r'''
void foo(^a) {}
''');

    _assertHasClass(text: 'Future');
    _assertHasClass(text: 'String');
  }

  Future<void> test_filterSort_byPattern_location_statement() async {
    await _compute(r'''
void f() {
  F^
  0;
}
''');

    _assertHasClass(text: 'Future');
    _assertNoClass(text: 'String');
  }

  Future<void> test_filterSort_byPattern_preferPrefix() async {
    await _compute(r'''
class Foobar {}
class Falcon {}
var a = Fo^;
''');

    _assertOrder([
      _assertHasClass(text: 'Foobar'),
      _assertHasClass(text: 'Falcon'),
    ]);
  }

  Future<void> test_filterSort_namedArgument_hasPrefix() async {
    await _compute(r'''
void foo({int aaa, int bbb});

void f() {
  foo(a^);
}
''');

    _assertHasNamedArgument(name: 'aaa');
    _assertNoNamedArgument(name: 'bbb');
  }

  Future<void> test_filterSort_namedArgument_noPrefix() async {
    await _compute(r'''
void foo({int aaa, int bbb});

void f() {
  foo(^);
}
''');

    _assertHasNamedArgument(name: 'aaa');
    _assertHasNamedArgument(name: 'bbb');
  }

  Future<void> test_filterSort_namedArgument_noPrefix_beforeOther() async {
    await _compute(r'''
void foo({int aaa = 0, int aab = 0}) {}

voif f() {
  foo(
    ^
    aaa: 0,
  );
}

''');

    _assertHasNamedArgument(name: 'aab');
  }

  Future<void> test_filterSort_preferLocal() async {
    await _compute(r'''
var a = 0;
void f() {
  var b = 0;
  var v = ^;
}
''');

    _assertOrder([
      _assertHasLocalVariable(text: 'b'),
      _assertHasTopLevelVariable(text: 'a'),
    ]);
  }

  Future<void> test_filterSort_sortByName() async {
    await _compute(r'''
void f() {
  var a = 0;
  var b = 0;
  var v = ^;
}
''');

    _assertOrder([
      _assertHasLocalVariable(text: 'b'),
      _assertHasLocalVariable(text: 'a'),
    ]);
  }

  Future<void> test_limitedResolution_class_constructor_body() async {
    _configureToCheckNotResolved(
      identifiers: {'print'},
    );

    await _compute(r'''
class A<T> {
  int f = 0;

  A(int a) : f = 1 {
    ^
  }

  void foo() {
    print(0);
  }
}
''');

    _assertHasClass(text: 'A');
    _assertHasClass(text: 'String');
    _assertHasConstructor(text: 'A');
    _assertHasFunction(text: 'print');
    _assertHasMethod(text: 'foo');
    _assertHasParameter(text: 'a');
    _assertHasTypeParameter(text: 'T');
  }

  Future<void> test_limitedResolution_class_field_startWithType() async {
    _configureToCheckNotResolved(
      identifiers: {'print'},
    );

    await _compute(r'''
class A {
  void foo() {
    print(0);
  }

  Str^
}
''');

    _assertHasClass(text: 'String');
  }

  Future<void> test_limitedResolution_class_method_body() async {
    _configureToCheckNotResolved(
      identifiers: {'print'},
    );

    await _compute(r'''
class A<T> {
  void foo() {
    print(0);
  }

  void bar<U>(int a) {
    ^
  }
}

class B {}

enum E { e }
''');

    _assertHasClass(text: 'A');
    _assertHasClass(text: 'B');
    _assertHasClass(text: 'String');
    _assertHasConstructor(text: 'A');
    _assertHasConstructor(text: 'B');
    _assertHasEnum(text: 'E');
    _assertHasMethod(text: 'foo');
    _assertHasMethod(text: 'bar');
    _assertHasParameter(text: 'a');
    _assertHasTypeParameter(text: 'T');
    _assertHasTypeParameter(text: 'U');
  }

  Future<void> test_limitedResolution_class_method_body2() async {
    _configureToCheckNotResolved(
      identifiers: {'print'},
    );

    await _compute(r'''
class A {
  void foo() {}
}

abstract class B {
  A get a;

  void notResolved() {
    print(0);
  }

  void completionTarget() {
    a.^;
  }
}
''');

    _assertHasGetter(text: 'hashCode');
    _assertHasMethod(text: 'foo');
  }

  Future<void> test_limitedResolution_class_method_parameterType() async {
    _configureToCheckNotResolved(
      identifiers: {'print'},
    );

    await _compute(r'''
class A {
  void foo() {
    print(0);
  }

  void bar(Str^) {}
}
''');

    _assertHasClass(text: 'String');
  }

  Future<void>
      test_limitedResolution_class_method_returnType_hasPartial() async {
    _configureToCheckNotResolved(
      identifiers: {'print'},
    );

    await _compute(r'''
class A {
  void foo() {
    print(0);
  }

  Str^ bar() {}
}
''');

    _assertHasClass(text: 'String');
  }

  Future<void> test_limitedResolution_hasPart() async {
    newFile('/workspace/dart/test/lib/a.dart', r'''
part of 'test.dart';
class A {}
''');

    await _compute(r'''
part 'a.dart';
^
''');

    _assertHasClass(text: 'int');
    _assertHasClass(text: 'A');
  }

  Future<void> test_limitedResolution_inPart_partOfName() async {
    newFile('/workspace/dart/test/lib/a.dart', r'''
library my_lib;
part 'test.dart';
class A {}
''');

    await _compute(r'''
part of my_lib;
^
''');

    _assertHasClass(text: 'int');
    _assertHasClass(text: 'A');
  }

  Future<void> test_limitedResolution_inPart_partOfUri() async {
    newFile('/workspace/dart/test/lib/a.dart', r'''
part 'test.dart';
class A {}
''');

    await _compute(r'''
part of 'a.dart';
^
''');

    _assertHasClass(text: 'int');
    _assertHasClass(text: 'A');
  }

  Future<void> test_limitedResolution_inPart_partOfUri_doesNotExist() async {
    await _compute(r'''
part of 'a.dart';
class A {}
^
''');

    _assertHasClass(text: 'int');
    _assertHasClass(text: 'A');
  }

  Future<void> test_limitedResolution_mixin_method_body() async {
    _configureToCheckNotResolved(
      identifiers: {'print'},
    );

    await _compute(r'''
class A {
  void foo() {}
}

mixin M {
  A get a;

  void notResolved() {
    print(0);
  }

  void completionTarget() {
    a.^;
  }
}
''');

    _assertHasGetter(text: 'hashCode');
    _assertHasMethod(text: 'foo');
  }

  Future<void> test_limitedResolution_path_hasSpace() async {
    testPath = convertPath('/workspace/dart/test name/lib/a.dart');
    await _compute(r'''
class A {}
^
''');

    _assertHasClass(text: 'int');
    _assertHasClass(text: 'A');
  }

  Future<void> test_limitedResolution_unit_function_body() async {
    _configureToCheckNotResolved(
      identifiers: {'print'},
    );

    await _compute(r'''
void foo() {
  print(0);
}

void bar(int a) {
  ^
}
''');

    _assertHasFunction(text: 'foo');
    _assertHasParameter(text: 'a');
  }

  Future<void> test_localTypeInference() async {
    await _compute(r'''
void foo() {
  var a = 0;
  a.^
}
''');

    _assertHasGetter(text: 'isEven');
  }

  Future<void> test_warmUp_cachesImportedLibraries() async {
    var aPath = convertPath('/workspace/dart/test/lib/a.dart');
    newFile(aPath, r'''
class A {}
''');

    var bPath = convertPath('/workspace/dart/test/lib/b.dart');
    newFile(bPath, r'''
import 'a.dart';
''');

    // Pre-cache `a.dart` using import in `b.dart`
    await _newComputer().warmUp([bPath]);
    _assertComputedImportedLibraries([aPath], hasCore: true);

    // Now we complete in `test.dart`, and `a.dart` is already cached.
    await _compute(r'''
import 'a.dart';
^
''');
    _assertComputedImportedLibraries([]);
    _assertHasClass(text: 'A');
  }

  void _assertComputedImportedLibraries(
    List<String> expected, {
    bool hasCore = false,
  }) {
    expected = expected.map(convertPath).toList();

    if (hasCore) {
      var corePath = convertPath('/sdk/lib/core/core.dart');
      expected.add(corePath);
    }

    expect(
      _computer.computedImportedLibraries,
      unorderedEquals(expected),
    );
  }

  CompletionSuggestion _assertHasClass({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.CLASS,
    );
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  void _assertHasCompletion({required String text}) {
    var matching = _matchingCompletions(text: text);
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
  }

  CompletionSuggestion _assertHasConstructor({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.CONSTRUCTOR,
    );
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  CompletionSuggestion _assertHasEnum({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.ENUM,
    );
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  CompletionSuggestion _assertHasFunction({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.FUNCTION,
    );
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  CompletionSuggestion _assertHasGetter({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.GETTER,
    );
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  CompletionSuggestion _assertHasKeyword({required String text}) {
    var matching = _matchingKeywordCompletions(text: text);
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  CompletionSuggestion _assertHasLocalVariable({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.LOCAL_VARIABLE,
    );
    expect(
      matching,
      hasLength(1),
      reason: 'Expected exactly one completion in $_suggestions',
    );
    return matching.single;
  }

  CompletionSuggestion _assertHasMethod({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.METHOD,
    );
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  CompletionSuggestion _assertHasNamedArgument({required String name}) {
    var matching = _matchingNamedArgumentSuggestions(name: name);
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  void _assertHasOperationPerformance(List<String> path) {
    var current = _completionResult.performance.operations;
    for (var name in path) {
      var child = current.getChild(name);
      expect(child, isNotNull, reason: "No '$name' in $current");
      current = child!;
    }
  }

  CompletionSuggestion _assertHasParameter({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.PARAMETER,
    );
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  CompletionSuggestion _assertHasTopLevelVariable({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.TOP_LEVEL_VARIABLE,
    );
    expect(
      matching,
      hasLength(1),
      reason: 'Expected exactly one completion in $_suggestions',
    );
    return matching.single;
  }

  CompletionSuggestion _assertHasTypeParameter({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.TYPE_PARAMETER,
    );
    expect(matching, hasLength(1), reason: 'Expected exactly one completion');
    return matching.single;
  }

  void _assertNoClass({required String text}) {
    var matching = _matchingCompletions(
      text: text,
      elementKind: ElementKind.CLASS,
    );
    expect(matching, isEmpty, reason: 'Expected zero completions');
  }

  void _assertNoKeyword({required String text}) {
    var matching = _matchingKeywordCompletions(text: text);
    expect(matching, isEmpty, reason: 'Expected zero completions');
  }

  void _assertNoNamedArgument({required String name}) {
    var matching = _matchingNamedArgumentSuggestions(name: name);
    expect(matching, isEmpty, reason: 'Expected zero completions');
  }

  void _assertOrder(List<CompletionSuggestion> suggestions) {
    var lastIndex = -2;
    for (var suggestion in suggestions) {
      var index = _suggestions.indexOf(suggestion);
      expect(index, isNonNegative, reason: '$suggestion');
      expect(index, greaterThan(lastIndex), reason: '$suggestion');
      lastIndex = index;
    }
  }

  Future<void> _compute(String content) async {
    var context = _updateFile(content);

    _completionResult = await _newComputer().compute(
      path: convertPath(testPath),
      line: context.line,
      column: context.character,
      testResolvedUnit: _testResolvedUnit,
    );
    _suggestions = _completionResult.suggestions;
  }

  /// Configure the [CiderCompletionComputer] to check that when resolving
  /// for completion we don't resolve unnecessary node.
  void _configureToCheckNotResolved({required Set<String> identifiers}) {
    _testResolvedUnit = (resolvedUnitResult) {
      var unit = resolvedUnitResult.parsedUnit;
      unit.accept(
        FunctionAstVisitor(
          simpleIdentifier: (node) {
            if (identifiers.contains(node.name) && node.staticElement != null) {
              fail('Unexpectedly resolved node: $node');
            }
          },
        ),
      );
    };
  }

  /// TODO(scheglov) Implement incremental updating
  void _createFileResolver() {
    createFileResolver();
  }

  List<CompletionSuggestion> _matchingCompletions({
    required String text,
    ElementKind? elementKind,
  }) {
    return _suggestions.where((e) {
      if (e.completion != text) {
        return false;
      }

      if (elementKind != null && e.element!.kind != elementKind) {
        return false;
      }

      return true;
    }).toList();
  }

  List<CompletionSuggestion> _matchingKeywordCompletions({
    required String text,
  }) {
    return _suggestions.where((e) {
      if (e.completion != text) {
        return false;
      }
      return e.kind == CompletionSuggestionKind.KEYWORD;
    }).toList();
  }

  List<CompletionSuggestion> _matchingNamedArgumentSuggestions({
    required String name,
  }) {
    return _suggestions.where((e) {
      if (e.kind != CompletionSuggestionKind.NAMED_ARGUMENT) {
        return false;
      }

      if (!e.completion.startsWith('$name:')) {
        return false;
      }

      return true;
    }).toList();
  }

  CiderCompletionComputer _newComputer() {
    return _computer = CiderCompletionComputer(
      logger,
      _completionCache,
      fileResolver,
    );
  }

  _CompletionContext _updateFile(String content) {
    var offset = content.indexOf('^');
    expect(offset, isPositive, reason: 'Expected to find ^');
    expect(content.indexOf('^', offset + 1), -1, reason: 'Expected only one ^');

    var lineInfo = LineInfo.fromContent(content);
    var location = lineInfo.getLocation(offset);

    content = content.substring(0, offset) + content.substring(offset + 1);
    newFile(testPath, content);

    return _CompletionContext(
      content,
      offset,
      location.lineNumber - 1,
      location.columnNumber - 1,
    );
  }
}

class _CompletionContext {
  final String content;
  final int offset;
  final int line;
  final int character;

  _CompletionContext(this.content, this.offset, this.line, this.character);
}
