// 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:analysis_server/lsp_protocol/protocol.dart';
import 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../utils/test_code_extensions.dart';
import 'server_abstract.dart';

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

@reflectiveTest
class ReferencesTest extends AbstractLspAnalysisServerTest {
  Future<void> test_acrossFiles_includeDeclaration() async {
    var otherContent = '''
import 'main.dart';

void f() {
  [!foo!]();
}
''';

    var mainContent = '''
/// Ensure the function is on a line that
/// does not exist in the mainContents file
/// to ensure we're translating offsets to line/col
/// using the correct file's LineInfo
/// ...
/// ...
/// ...
/// ...
/// ...
[!^foo!]() {}
''';

    await _checkRanges(
      mainContent,
      otherContent: otherContent,
      includeDeclarations: true,
    );
  }

  Future<void> test_acrossFiles_withoutDeclaration() async {
    var otherContent = '''
import 'main.dart';

void f() {
  [!foo!]();
}
''';

    var mainContent = '''
/// Ensure the function is on a line that
/// does not exist in the mainContents file
/// to ensure we're translating offsets to line/col
/// using the correct file's LineInfo
/// ...
/// ...
/// ...
/// ...
/// ...
^foo() {}
''';

    await _checkRanges(mainContent, otherContent: otherContent);
  }

  Future<void> test_field_decalaration_getterSetter() async {
    var content = '''
class MyClass {
  String field^ = '';
}

void f() {
  MyClass()./*[0*/field/*0]*/ = '';
  print(MyClass()./*[1*/field/*1]*/);

  var myInstance = MyClass();
  myInstance./*[2*/field/*2]*/ = '';
  print(myInstance./*[3*/field/*3]*/);
  myInstance./*[4*/field/*4]*/ += myInstance./*[5*/field/*5]*/;
}
''';

    await _checkRanges(content);
  }

  Future<void> test_field_decalaration_initializingFormal() async {
    // References on the field should find the initializing formal, the
    // reference to the getter and the constructor argument.
    var content = '''
class AAA {
  final String? aa^a;
  const AAA({this./*[0*/aaa/*0]*/});
}

class BBB extends AAA {
  BBB({super./*[1*/aaa/*1]*/});
}

final a = AAA(/*[2*/aaa/*2]*/: '')./*[3*/aaa/*3]*/;
''';

    await _checkRanges(content);
  }

  Future<void> test_forEachElement_blockBody() async {
    var content = '''
void f(List<int> values) {
  [for (final val^ue in values) [!value!] * 2];
}
''';

    await _checkRanges(content);
  }

  Future<void> test_forEachElement_expressionBody() async {
    var content = '''
Object f() => [for (final val^ue in []) [!value!] * 2];
''';

    await _checkRanges(content);
  }

  Future<void> test_forEachElement_topLevel() async {
    var content = '''
final a = [for (final val^ue in []) [!value!] * 2];
''';

    await _checkRanges(content);
  }

  Future<void> test_function_startOfParameterList() async {
    var content = '''
foo^() {
  [!foo!]();
}
''';

    await _checkRanges(content);
  }

  Future<void> test_function_startOfTypeParameterList() async {
    var content = '''
foo^<T>() {
  [!foo!]();
}
''';

    await _checkRanges(content);
  }

  Future<void> test_getter_decalaration_getterSetter() async {
    var content = '''
class MyClass {
  String get field^ => '';
  set field(String _) {}
}

void f() {
  MyClass()./*[0*/field/*0]*/ = '';
  print(MyClass()./*[1*/field/*1]*/);

  var myInstance = MyClass();
  myInstance./*[2*/field/*2]*/ = '';
  print(myInstance./*[3*/field/*3]*/);
  myInstance./*[4*/field/*4]*/ += myInstance./*[5*/field/*5]*/;
}
''';

    await _checkRanges(content);
  }

  Future<void> test_getter_invocation_getterSetter() async {
    var content = '''
class MyClass {
  String get field => '';
  set field(String _) {}
}

void f() {
  MyClass()./*[0*/field/*0]*/ = '';
  print(MyClass()./*[1*/fi^eld/*1]*/);

  var myInstance = MyClass();
  myInstance./*[2*/field/*2]*/ = '';
  print(myInstance./*[3*/field/*3]*/);
  myInstance./*[4*/field/*4]*/ += myInstance./*[5*/field/*5]*/;
}
''';

    await _checkRanges(content);
  }

  Future<void> test_import_prefix_declaration() async {
    var content = '''
import 'dart:async' as asy^nc;

/*[0*/async/*0]*/.Future<String>? f() {}
/*[1*/async/*1]*/.Future<String>? g() {}
''';

    await _checkRanges(content);
  }

  Future<void> test_import_prefix_reference() async {
    var content = '''
import 'dart:async' as async;

/*[0*/^async/*0]*/.Future<String>? f() {}
/*[1*/async/*1]*/.Future<String>? g() {}
''';

    await _checkRanges(content);
  }

  Future<void> test_initializingFormal_argument_withDeclaration() async {
    // Find references on an initializing formal argument should include
    // all references to the field too.
    var content = '''
class AAA {
  String? /*[0*/aaa/*0]*/;
  AAA({this./*[1*/aaa/*1]*/});
}

void f() {
  final a = AAA(/*[2*/a^aa/*2]*/: '');
  var x = a./*[3*/aaa/*3]*/;
  a./*[4*/aaa/*4]*/ = '';
}
''';

    await _checkRanges(content, includeDeclarations: true);
  }

  Future<void> test_initializingFormal_argument_withoutDeclaration() async {
    // Find references on an initializing formal argument should include
    // all references to the field too. The field is not included
    // because we didn't request the declaration.
    var content = '''
class AAA {
  String? aaa;
  AAA({this./*[0*/aaa/*0]*/});
}

void f() {
  final a = AAA(/*[1*/a^aa/*1]*/: '');
  var x = a./*[2*/aaa/*2]*/;
  a./*[3*/aaa/*3]*/ = '';
}
''';

    await _checkRanges(content);
  }

  Future<void> test_initializingFormal_parameter_withDeclaration() async {
    // Find references on an initializing formal parameter should include
    // all references to the field too.
    var content = '''
class AAA {
  String? /*[0*/aaa/*0]*/;
  AAA({this./*[1*/aa^a/*1]*/});
}

void f() {
  final a = AAA(/*[2*/aaa/*2]*/: '');
  var x = a./*[3*/aaa/*3]*/;
  a./*[4*/aaa/*4]*/ = '';
}
''';

    await _checkRanges(content, includeDeclarations: true);
  }

  Future<void> test_initializingFormal_parameter_withoutDeclaration() async {
    // Find references on an initializing formal parameter should include
    // all references to the field too. The field is not included
    // because we didn't request the declaration.
    var content = '''
class AAA {
  String? aaa;
  AAA({this./*[0*/aa^a/*0]*/});
}

class BBB extends AAA {
  BBB({super./*[1*/aaa/*1]*/});
}

void f() {
  final a = AAA(/*[2*/aaa/*2]*/: '');
  var x = a./*[3*/aaa/*3]*/;
  a./*[4*/aaa/*4]*/ = '';
}
''';

    await _checkRanges(content);
  }

  Future<void> test_method_startOfParameterList() async {
    var content = '''
class A {
  foo^() {
    [!foo!]();
  }
}
''';

    await _checkRanges(content);
  }

  Future<void> test_method_startOfTypeParameterList() async {
    var content = '''
class A {
  foo^<T>() {
    [!foo!]();
  }
}
''';

    await _checkRanges(content);
  }

  Future<void> test_nonDartFile() async {
    newFile(pubspecFilePath, simplePubspecContent);
    await initialize();

    var res = await getReferences(pubspecFileUri, startOfDocPos);
    expect(res, isEmpty);
  }

  Future<void> test_pattern_object_withDeclaration() async {
    var content = '''
class A {
  int get i => 0;
}

int f(Object o) {
  switch (o) {
    case A(:var /*[0*/^i/*0]*/):
      return /*[1*/i/*1]*/;
  }
  return 0;
}
''';

    await _checkRanges(content, includeDeclarations: true);
  }

  Future<void> test_pattern_object_withoutDeclaration() async {
    var content = '''
class A {
  int get i => 0;
}

int f(Object o) {
  switch (o) {
    case A(:var ^i):
      return [!i!];
  }
  return 0;
}
''';

    await _checkRanges(content);
  }

  Future<void> test_setter_decalaration_getterSetter() async {
    var content = '''
class MyClass {
  String get field => '';
  set fie^ld(String _) {}
}

void f() {
  MyClass()./*[0*/field/*0]*/ = '';
  print(MyClass()./*[1*/field/*1]*/);

  var myInstance = MyClass();
  myInstance./*[2*/field/*2]*/ = '';
  print(myInstance./*[3*/field/*3]*/);
  myInstance./*[4*/field/*4]*/ += myInstance./*[5*/field/*5]*/;
}
''';

    await _checkRanges(content);
  }

  Future<void> test_setter_invocation_getterSetter() async {
    var content = '''
class MyClass {
  String get field => '';
  set field(String _) {}
}

void f() {
  MyClass()./*[0*/fie^ld/*0]*/ = '';
  print(MyClass()./*[1*/field/*1]*/);

  var myInstance = MyClass();
  myInstance./*[2*/field/*2]*/ = '';
  print(myInstance./*[3*/field/*3]*/);
  myInstance./*[4*/field/*4]*/ += myInstance./*[5*/field/*5]*/;
}
''';

    await _checkRanges(content);
  }

  Future<void> test_singleFile_withoutDeclaration() async {
    var content = '''
f^oo() {
  [!foo!]();
}
''';

    await _checkRanges(content);
  }

  Future<void> test_type() async {
    var content = '''
class A^aa<T> {}

[!Aaa!]<String>? a;
''';

    await _checkRanges(content);
  }

  Future<void> test_type_generic_end() async {
    var content = '''
class Aaa^<T> {}

[!Aaa!]<String>? a;
''';

    await _checkRanges(content);
  }

  Future<void> test_unopenFile() async {
    var code = TestCode.parse('''
    f^oo() {
      [!foo!]();
    }
    ''');

    newFile(mainFilePath, code.code);
    await initialize();
    var res = await getReferences(mainFileUri, code.position.position);

    var expected = [
      for (final range in code.ranges)
        Location(uri: mainFileUri, range: range.range),
    ];

    expect(res, unorderedEquals(expected));
  }

  Future<void> _checkRanges(
    String mainContent, {
    String? otherContent,
    bool includeDeclarations = false,
  }) async {
    var mainCode = TestCode.parse(mainContent);
    var otherCode = otherContent != null ? TestCode.parse(otherContent) : null;
    var otherFileUri = toUri(join(projectFolderPath, 'lib', 'other.dart'));

    await initialize();
    await openFile(mainFileUri, mainCode.code);
    if (otherCode != null) {
      await openFile(otherFileUri, otherCode.code);
    }
    var res = await getReferences(
      mainFileUri,
      mainCode.position.position,
      includeDeclarations: includeDeclarations,
    );

    var expected = [
      for (final range in mainCode.ranges)
        Location(uri: mainFileUri, range: range.range),
      if (otherCode != null)
        for (final range in otherCode.ranges)
          Location(uri: otherFileUri, range: range.range),
    ];

    // Checking sets produces a better failure message than lists
    // (it'll show which item is missing instead of just saying
    // the lengths are different), so check that first.
    expect(res.toSet(), expected.toSet());
    // But also check the list in case there were unexpected duplicates.
    expect(res, unorderedEquals(expected));
  }
}
