// 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:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../analysis_server_base.dart';
import '../services/completion/dart/completion_check.dart';
import '../services/completion/dart/completion_printer.dart' as printer;
import '../services/completion/dart/text_expectations.dart';
import 'impl/completion_driver.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(BasicCompletionTest);
    defineReflectiveTests(CompletionWithSuggestionsTest);
  });
}

typedef SuggestionMatcher = bool Function(CompletionSuggestion suggestion);

abstract class AbstractCompletionDriverTest
    extends PubPackageAnalysisServerTest {
  late CompletionDriver driver;

  late List<CompletionSuggestion> suggestions;

  late CompletionResponseForTesting response;

  /// The configuration used by [assertResponse] to limit the number of
  /// suggestions that will be compared by a test. The reasons for the filter
  /// are
  /// - to prevent uninteresting changes to the SDK from breaking the completion
  ///   tests, and
  /// - to keep the expected response text shorter.
  ///
  /// The default filter, initialized in [setUp], prints
  /// - identifier suggestions consisting of a single letter followed by one or
  ///   more digits,
  /// - identifier suggestions that are in the set of [allowedIdentifiers], and
  /// - non-identifier suggestions.
  ///
  /// Tests can override this configuration to change the set of suggestions to
  /// be printed.
  late printer.Configuration printerConfiguration;

  /// A set of identifiers that will be included in the printed version of the
  /// suggestions. Individual tests can replace the default set.
  Set<String> allowedIdentifiers = const {};

  /// A set of completion kinds that should be included in the printed version
  /// of the suggestions. Individual tests can replace the default set.
  Set<CompletionSuggestionKind> allowedKinds = {};

  /// Whether keywords should be included in the text to be compared.
  bool includeKeywords = true;

  /// Return `true` if closures (suggestions starting with a left paren) should
  /// be included in the text to be compared.
  bool get includeClosures => false;

  /// Return `true` if overrides should be included in the text to be compared.
  bool get includeOverrides => true;

  @override
  Future<List<CompletionSuggestion>> addTestFile(
    String content, {
    int? offset,
  }) async {
    driver.addTestFile(content, offset: offset);

    // Wait after adding the test file, this might affect diagnostics.
    await pumpEventQueue(times: 1000);

    // For sanity, ensure that there are no errors recorded for project files
    // since that may lead to unexpected results.
    _assertNoErrorsInProjectFiles();

    await getSuggestions();
    return suggestions;
  }

  void assertNoSuggestion({
    required String completion,
    ElementKind? element,
    CompletionSuggestionKind? kind,
    String? file,
  }) {
    expect(
      suggestionsWith(
        completion: completion,
        element: element,
        kind: kind,
        file: file,
      ),
      isEmpty,
    );
  }

  /// Asserts that the [response] has the [expected] textual dump produced
  /// using [printerConfiguration].
  void assertResponse(String expected, {String where = ''}) {
    var buffer = StringBuffer();
    printer.CompletionResponsePrinter(
      buffer: buffer,
      configuration: printerConfiguration,
      response: response,
    ).writeResponse();
    var actual = buffer.toString();

    if (actual != expected) {
      if (where.isEmpty) {
        var target =
            driver.server.server.completionState.currentRequest?.target;
        if (target != null) {
          var containingNode = target.containingNode.runtimeType;
          var entity = target.entity;
          where = ' (containingNode = $containingNode, entity = $entity)';
        }
      }
      TextExpectationsCollector.add(actual);
      fail('''
The actual suggestions do not match the expected suggestions$where.

To accept the current state change the expectation to
\r${'-' * 64}
\r${actual.trimRight().split('\n').join('\n\r')}
\r${'-' * 64}
''');
    }
  }

  void assertSuggestion({
    required String completion,
    ElementKind? element,
    CompletionSuggestionKind? kind,
    String? file,
    String? libraryUri,
  }) {
    expect(
      suggestionWith(
        completion: completion,
        element: element,
        kind: kind,
        file: file,
        libraryUri: libraryUri,
      ),
      isNotNull,
    );
  }

  // TODO(scheglov): Use it everywhere instead of [addTestFile].
  // ignore:unreachable_from_main
  Future<void> computeSuggestions(String content) async {
    // Give the server time to create analysis contexts.
    await pumpEventQueue(times: 1000);

    await addTestFile(content);

    // Extract the internal request object.
    var dartRequest = server.completionState.currentRequest;

    response = CompletionResponseForTesting(
      requestOffset: driver.completionOffset,
      requestLocationName: dartRequest?.collectorLocationName,
      opTypeLocationName: dartRequest?.opType.completionLocation,
      replacementOffset: driver.replacementOffset,
      replacementLength: driver.replacementLength,
      isIncomplete: false, // TODO(scheglov): not correct
      suggestions: suggestions,
    );
  }

  Future<List<CompletionSuggestion>> getSuggestions() async {
    suggestions = await driver.getSuggestions();
    return suggestions;
  }

  @override
  Future<void> setUp() async {
    super.setUp();

    writeTestPackagePubspecYamlFile(r'''
name: test
''');

    driver = CompletionDriver(server: this);
    await driver.createProject();

    // TODO(pq): add logic (possibly to driver) that waits for SDK suggestions

    printerConfiguration = printer.Configuration(
      filter: (suggestion) {
        var kind = suggestion.kind;
        if (kind == CompletionSuggestionKind.IDENTIFIER ||
            kind == CompletionSuggestionKind.INVOCATION) {
          var completion = suggestion.completion;
          if (includeClosures && completion.startsWith('(')) {
            return true;
          }
          var periodIndex = completion.indexOf('.');
          if (periodIndex > 0) {
            completion = completion.substring(0, periodIndex);
          }
          return RegExp(r'^_?[a-zA-Z][0-9]+$').hasMatch(completion) ||
              allowedIdentifiers.contains(completion);
        } else if (kind == CompletionSuggestionKind.KEYWORD) {
          return includeKeywords;
        } else if (kind == CompletionSuggestionKind.OVERRIDE) {
          return includeOverrides;
        } else if (allowedKinds.contains(kind)) {
          return true;
        }
        return true;
      },
    );
  }

  SuggestionMatcher suggestionHas({
    required String completion,
    ElementKind? element,
    CompletionSuggestionKind? kind,
    String? file,
    String? libraryUri,
  }) => (CompletionSuggestion s) {
    if (s.completion != completion) {
      return false;
    }
    if (element != null && s.element?.kind != element) {
      return false;
    }
    if (kind != null && s.kind != kind) {
      return false;
    }

    if (file != null && s.element?.location?.file != convertPath(file)) {
      return false;
    }
    if (libraryUri != null && s.libraryUri != libraryUri) {
      return false;
    }
    return true;
  };

  Iterable<CompletionSuggestion> suggestionsWith({
    required String completion,
    ElementKind? element,
    CompletionSuggestionKind? kind,
    String? file,
    String? libraryUri,
  }) => suggestions.where(
    suggestionHas(
      completion: completion,
      element: element,
      kind: kind,
      file: file,
      libraryUri: libraryUri,
    ),
  );

  CompletionSuggestion suggestionWith({
    required String completion,
    ElementKind? element,
    CompletionSuggestionKind? kind,
    String? file,
    String? libraryUri,
  }) {
    var matches = suggestionsWith(
      completion: completion,
      element: element,
      kind: kind,
      file: file,
      libraryUri: libraryUri,
    );
    expect(matches, hasLength(1));
    return matches.first;
  }

  void _assertNoErrorsInProjectFiles() {
    var errors = <AnalysisError>[];
    driver.filesErrors.forEach((file, fileErrors) {
      // Completion test files are likely to be incomplete and so may have
      // errors
      if (file != convertPath(testFilePath)) {
        errors.addAll(fileErrors);
      }
    });
    expect(errors, isEmpty);
  }
}

@reflectiveTest
class BasicCompletionTest extends AbstractCompletionDriverTest
    with BasicCompletionTestCases {}

mixin BasicCompletionTestCases on AbstractCompletionDriverTest {
  /// Duplicates (and potentially replaces) [DeprecatedMemberRelevanceTest].
  Future<void> test_deprecated_member_relevance() async {
    await addTestFile('''
class A {
  void a1() { }
  @deprecated
  void a2() { }
}

void f() {
  var a = A();
  a.^
}
''');

    expect(
      suggestionWith(
        completion: 'a2',
        element: ElementKind.METHOD,
        kind: CompletionSuggestionKind.INVOCATION,
      ).relevance,
      lessThan(
        suggestionWith(
          completion: 'a1',
          element: ElementKind.METHOD,
          kind: CompletionSuggestionKind.INVOCATION,
        ).relevance,
      ),
    );
  }
}

@reflectiveTest
class CompletionWithSuggestionsTest extends AbstractCompletionDriverTest
    with CompletionWithSuggestionsTestCases {}

mixin CompletionWithSuggestionsTestCases on AbstractCompletionDriverTest {
  Future<void> test_project_filterImports_defaultConstructor() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {}
''');

    newFile('$testPackageLibPath/b.dart', r'''
export 'a.dart';
''');

    await addTestFile('''
import 'a.dart';
void f() {
  ^
}
''');

    assertSuggestion(
      completion: 'A',
      element: ElementKind.CONSTRUCTOR,
      kind: CompletionSuggestionKind.INVOCATION,
    );
  }

  /// See: https://github.com/dart-lang/sdk/issues/40620
  Future<void> test_project_filterImports_enumValues() async {
    newFile('$testPackageLibPath/a.dart', r'''
enum E {
  e,
}
''');

    newFile('$testPackageLibPath/b.dart', r'''
export 'a.dart';
''');

    await addTestFile('''
import 'a.dart';
void f() {
  E v = ^
}
''');
    assertSuggestion(completion: 'E.e', element: ElementKind.ENUM_CONSTANT);
  }

  /// See: https://github.com/dart-lang/sdk/issues/40620
  Future<void> test_project_filterImports_namedConstructors() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {
  A.a();
}
''');

    newFile('$testPackageLibPath/b.dart', r'''
export 'a.dart';
''');

    await addTestFile('''
import 'a.dart';
void f() {
  ^
}
''');

    assertSuggestion(
      completion: 'A.a',
      element: ElementKind.CONSTRUCTOR,
      kind: CompletionSuggestionKind.INVOCATION,
    );
  }

  Future<void> test_project_filterMultipleImports() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {}
''');

    newFile('$testPackageLibPath/b.dart', r'''
export 'a.dart';
''');

    await addTestFile('''
import 'a.dart';
import 'b.dart';
void f() {
  ^
}
''');

    assertSuggestion(completion: 'A', element: ElementKind.CLASS);
  }

  Future<void> test_project_lib() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {}
enum E {
  e,
}
extension Ex on A {}
mixin M { }
typedef T = Function(Object);
typedef T2 = double;
var v = 0;
''');

    await addTestFile('''
void f() {
  ^
}
''');

    assertSuggestion(
      completion: 'A',
      element: ElementKind.CONSTRUCTOR,
      kind: CompletionSuggestionKind.INVOCATION,
    );
    assertSuggestion(completion: 'A', element: ElementKind.CLASS);
    assertSuggestion(completion: 'E', element: ElementKind.ENUM);
    assertSuggestion(completion: 'Ex', element: ElementKind.EXTENSION);
    assertSuggestion(completion: 'M', element: ElementKind.MIXIN);
    assertSuggestion(completion: 'T', element: ElementKind.TYPE_ALIAS);
    assertSuggestion(completion: 'T2', element: ElementKind.TYPE_ALIAS);
    assertSuggestion(completion: 'v', element: ElementKind.TOP_LEVEL_VARIABLE);
  }

  Future<void> test_project_lib_fields_class() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {
  int f = 0;
}
''');

    await addTestFile('''
void m() {
  ^
}
''');

    assertNoSuggestion(completion: 'f');
  }

  Future<void> test_project_lib_getters_class() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {
  int get g => 0;
}
''');

    await addTestFile('''
void f() {
  ^
}
''');

    assertNoSuggestion(completion: 'g');
  }

  /// See: https://github.com/dart-lang/sdk/issues/40626
  Future<void> test_project_lib_getters_topLevel() async {
    newFile('$testPackageLibPath/a.dart', r'''
int get g => 0;
''');

    await addTestFile('''
void f() {
  ^
}
''');

    assertSuggestion(completion: 'g', element: ElementKind.GETTER);
  }

  Future<void> test_project_lib_methods_class() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {
  void foo() => 0;
}
''');

    await addTestFile('''
void f() {
  ^
}
''');

    assertNoSuggestion(completion: 'A.foo');
  }

  Future<void> test_project_lib_methods_static() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {
  static void foo() => 0;
}
''');

    await addTestFile('''
void f() {
  ^
}
''');

    assertNoSuggestion(completion: 'A.foo');
  }

  Future<void> test_project_lib_multipleExports() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {}
''');

    newFile('$testPackageLibPath/b.dart', r'''
export 'a.dart';
''');

    await addTestFile('''
void f() {
  ^
}
''');

    // Should be suggested from both libraries.
    assertSuggestion(
      completion: 'A',
      libraryUri: 'package:test/a.dart',
      element: ElementKind.CONSTRUCTOR,
      kind: CompletionSuggestionKind.INVOCATION,
    );
    assertSuggestion(
      completion: 'A',
      libraryUri: 'package:test/b.dart',
      element: ElementKind.CONSTRUCTOR,
      kind: CompletionSuggestionKind.INVOCATION,
    );
  }

  Future<void> test_project_lib_multipleExports_filteredByImport() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {}
''');

    newFile('$testPackageLibPath/b.dart', r'''
export 'a.dart';
''');

    await addTestFile('''
import 'b.dart';
void f() {
  ^
}
''');

    // Should be only one suggestion, which comes from the import of 'b.dart'.
    assertSuggestion(
      completion: 'A',
      element: ElementKind.CLASS,
      libraryUri: 'package:test/b.dart',
    );
  }

  Future<void> test_project_lib_multipleExports_filteredByLocal() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {}
''');

    await addTestFile('''
class A {}
void f() {
  ^
}
''');

    // Should be only one suggestion, which comes from local declaration.
    var suggestion = suggestionWith(
      completion: 'A',
      element: ElementKind.CLASS,
    );
    expect(suggestion, isNotNull);
    expect(suggestion.libraryUri, isNull);
  }

  Future<void> test_project_lib_setters_class() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {
  set s(int s) {}
}
''');

    await addTestFile('''
void f() {
  ^
}
''');

    assertNoSuggestion(completion: 's');
  }

  Future<void> test_project_lib_setters_static() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A {
  static set foo(int _) {}
}
''');

    await addTestFile('''
void f() {
  ^
}
''');

    assertNoSuggestion(completion: 'A.foo');
  }

  /// See: https://github.com/dart-lang/sdk/issues/40626
  Future<void> test_project_lib_setters_topLevel() async {
    newFile('$testPackageLibPath/a.dart', r'''
set s(int s) {}
''');

    await addTestFile('''
void f() {
  ^
}
''');

    assertSuggestion(completion: 's', element: ElementKind.SETTER);
  }

  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38739')
  Future<void>
  test_project_suggestionRelevance_constructorParameterType() async {
    newFile('$testPackageLibPath/a.dart', r'''
import 'b.dart';

class A {
  A.b({O o});
}
''');

    newFile('$testPackageLibPath/b.dart', r'''
class O { }
''');

    await addTestFile('''
import 'a.dart';

void f(List<String> args) {
  var a = A.b(o: ^)
}
''');

    expect(
      suggestionWith(
        completion: 'O',
        element: ElementKind.CONSTRUCTOR,
        kind: CompletionSuggestionKind.INVOCATION,
      ).relevance,
      greaterThan(
        suggestionWith(
          completion: 'args',
          element: ElementKind.PARAMETER,
          kind: CompletionSuggestionKind.INVOCATION,
        ).relevance,
      ),
    );
  }

  Future<void> test_project_suggestionRelevance_constructorsAndTypes() async {
    newFile('$testPackageLibPath/a.dart', r'''
class A { }
''');

    await addTestFile('''
import 'a.dart';

void f(List<String> args) {
  var a = ^
}
''');

    expect(
      suggestionWith(
        completion: 'A',
        element: ElementKind.CONSTRUCTOR,
      ).relevance,
      greaterThan(
        suggestionWith(completion: 'A', element: ElementKind.CLASS).relevance,
      ),
    );
  }

  /// See: https://github.com/dart-lang/sdk/issues/35529
  Future<void> test_project_suggestMixins() async {
    newFile('$testPackageLibPath/a.dart', r'''
mixin M { }
mixin class A { }
''');

    await addTestFile('''
class C extends Object with ^
''');

    assertSuggestion(completion: 'M', element: ElementKind.MIXIN);
    assertSuggestion(completion: 'A', element: ElementKind.CLASS);
  }

  Future<void> test_sdk_lib_future_isNotDuplicated() async {
    await addTestFile('''
void f() {
  ^
}
''');

    expect(
      suggestionsWith(
        completion: 'Future.value',
        file: '/sdk/lib/async/async.dart',
        element: ElementKind.CONSTRUCTOR,
        kind: CompletionSuggestionKind.INVOCATION,
      ),
      hasLength(1),
    );
  }

  Future<void> test_sdk_lib_suggestions() async {
    await addTestFile('''
void f() {
  ^
}
''');

    // A kind-filtered set of SDK suggestions.

    // Constructors should be visible.
    assertSuggestion(
      completion: 'Timer',
      file: '/sdk/lib/async/async.dart',
      element: ElementKind.CONSTRUCTOR,
      kind: CompletionSuggestionKind.INVOCATION,
    );

    // But not methods.
    assertNoSuggestion(
      // dart:async (StreamSubscription)
      completion: 'asFuture',
      element: ElementKind.METHOD,
      kind: CompletionSuggestionKind.INVOCATION,
    );

    // +  Functions.
    assertSuggestion(
      completion: 'print',
      file: '/sdk/lib/core/core.dart',
      element: ElementKind.FUNCTION,
      kind: CompletionSuggestionKind.INVOCATION,
    );
    assertSuggestion(
      completion: 'tan',
      file: '/sdk/lib/math/math.dart',
      element: ElementKind.FUNCTION,
      kind: CompletionSuggestionKind.INVOCATION,
    );

    // + Classes.
    assertSuggestion(
      completion: 'HashMap',
      file: '/sdk/lib/collection/collection.dart',
      element: ElementKind.CLASS,
    );

    // + Top level variables.
    assertSuggestion(
      completion: 'pi',
      file: '/sdk/lib/math/math.dart',
      element: ElementKind.TOP_LEVEL_VARIABLE,
    );

    // (No typedefs, enums, extensions defined in the Mock SDK.)
  }
}
