// Copyright (c) 2019, 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(ImplementationTest);
  });
}

@reflectiveTest
class ImplementationTest extends AbstractLspAnalysisServerTest {
  Future<void> test_class_excludesSelf() => _testMarkedContent('''
      abstract class ^[!A!] {}
      class B extends A {}
      class C extends A {}
    ''', expectResults: false);

  Future<void> test_class_excludesSuper() => _testMarkedContent('''
      abstract class [!A!] {}
      class ^B extends A {}
      class C extends A {}
    ''', expectResults: false);

  Future<void> test_class_sub() => _testMarkedContent('''
      abstract class ^A {}
      class /*[0*/B/*0]*/ extends A {}
      class /*[1*/C/*1]*/ extends A {}
    ''');

  Future<void> test_class_sub_underscore() => _testMarkedContent('''
      abstract class ^_ {}
      class /*[0*/B/*0]*/ extends _ {}
      class /*[1*/C/*1]*/ extends _ {}
    ''');

  Future<void> test_class_subSub() => _testMarkedContent('''
      abstract class ^A {}
      class /*[0*/B/*0]*/ extends A {}
      class /*[1*/C/*1]*/ extends A {}
      class /*[2*/D/*2]*/ extends B {}
      class /*[3*/E/*3]*/ extends B {}
      class /*[4*/F/*4]*/ extends E {}
    ''');

  Future<void> test_emptyResults() async {
    var content = '';

    await initialize();
    await openFile(mainFileUri, content);
    var res = await getImplementations(
      mainFileUri,
      startOfDocPos,
    );

    expect(res, isEmpty);
  }

  Future<void> test_getter_overriddenByField() => _testMarkedContent('''
      class B extends A {
        final String? [!a!] = null;
      }

      abstract class A {
        String? get a^;
      }
    ''');

  Future<void> test_getter_overriddenByField_underscore() =>
      _testMarkedContent('''
      class B extends A {
        final String? [!_!] = null;
      }

      abstract class A {
        String? get _^;
      }
    ''');

  Future<void> test_method_excludesClassesWithoutImplementations() =>
      _testMarkedContent('''
      abstract class A {
        void ^b() {}
      }

      class B extends A {}

      class [!E!] extends B {}
    ''', expectResults: false);

  Future<void> test_method_excludesSelf() => _testMarkedContent('''
      abstract class A {
        void ^[!b!]();
      }

      class B extends A {
        void b() {}
      }
    ''', expectResults: false);

  Future<void> test_method_excludesSuper() => _testMarkedContent('''
      abstract class A {
        void [!b!]();
      }

      class B extends A {
        void ^b() {}
      }
    ''', expectResults: false);

  Future<void> test_method_fromCallSite() => _testMarkedContent('''
      abstract class A {
        void b();
      }

      class B extends A {
        void /*[0*/b/*0]*/() {}
      }

      class C extends A {
        void /*[1*/b/*1]*/() {}
      }

      class D extends B {
        void /*[2*/b/*2]*/() {}
      }

      class E extends B {}

      class F extends E {
        void /*[3*/b/*3]*/() {}
      }

      void fromCallSite() {
        A e = new E();
        e.^b();
      }
    ''');

  Future<void> test_method_startOfParameterList() => _testMarkedContent('''
      abstract class A {
        void m^();
      }

      class B extends A {
        void [!m!]() {}
      }
    ''');

  Future<void> test_method_startOfTypeParameterList() => _testMarkedContent('''
      abstract class A {
        void m^<T>();
      }

      class B extends A {
        void [!m!]<T>() {}
      }
    ''');

  Future<void> test_method_sub() => _testMarkedContent('''
      abstract class A {
        void ^b();
      }

      class B extends A {
        void /*[0*/b/*0]*/() {}
      }

      class C extends A {
        void /*[1*/b/*1]*/() {}
      }
    ''');

  Future<void> test_method_sub_underscore() => _testMarkedContent('''
      abstract class A {
        void ^_();
      }

      class B extends A {
        void /*[0*/_/*0]*/() {}
      }

      class C extends A {
        void /*[1*/_/*1]*/() {}
      }
    ''');

  Future<void> test_method_subSub() => _testMarkedContent('''
      abstract class A {
        void ^b();
      }

      class B extends A {
        void /*[0*/b/*0]*/() {}
      }

      class D extends B {
        void /*[1*/b/*1]*/() {}
      }

      class E extends B {}

      class F extends E {
        void /*[2*/b/*2]*/() {}
      }
    ''');

  /// Check that implementations that come from mixins in other files return the
  /// correct location for the implementation.
  Future<void> test_mixins() async {
    var mixinsContent = r'''
import 'main.dart';

mixin MyMixin implements MyInterface {
  String get [!interfaceField!] => '';
}
''';
    var content = r'''
import 'other.dart';

class A with MyMixin {}
class B with MyMixin {}
class C implements MyInterface {
  String get [!interfaceField!] => '';
}

abstract class MyInterface {
  String get interf^aceField;
}
''';

    await _testMarkedContent(content, otherContent: mixinsContent);
  }

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

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

  /// Parses [content] using as [TestCode] and invokes the
  /// `textDocument/implementations` command at the marked location to verify
  /// the marked regions are returned as implementations.
  ///
  /// If [otherContent] is provided, will be written as `other.dart` alongside
  /// the file and any marked regions will also be verified.
  ///
  /// If [expectResults] is `false` then expects none of the ranges marked with
  /// `/*[0*/brackets/*0]*/` to be present in the results instead.
  Future<void> _testMarkedContent(
    String content, {
    String? otherContent,
    bool expectResults = true,
  }) async {
    var otherFilePath = join(projectFolderPath, 'lib', 'other.dart');
    var otherFileUri = pathContext.toUri(otherFilePath);
    var code = TestCode.parse(content);
    var otherCode = otherContent != null ? TestCode.parse(otherContent) : null;
    if (otherCode != null) {
      newFile(otherFilePath, otherCode.code);
    }
    newFile(mainFilePath, code.code);

    await initialize();

    var res = await getImplementations(
      mainFileUri,
      code.position.position,
    );

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

    if (expectResults) {
      expect(expectedLocations, isNotEmpty);
      expect(res, unorderedEquals(expectedLocations));
    } else {
      for (var location in expectedLocations) {
        expect(res, isNot(contains(location)));
      }
    }
  }
}
