// 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',
      'DartCompletionManager - 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 _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);
}
