// 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_generated.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.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 {}
    ''', shouldMatch: false);

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

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

  Future<void> test_class_subSub() => _testMarkedContent('''
      abstract class ^A {}
      class [[B]] extends A {}
      class [[C]] extends A {}
      class [[D]] extends B {}
      class [[E]] extends B {}
      class [[F]] extends E {}
    ''');

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

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

    expect(res, isEmpty);
  }

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

      class B extends A {}

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

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

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

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

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

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

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

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

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

      class E extends B {}

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

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

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

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

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

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

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

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

      class E extends B {}

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

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

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

  /// Takes an input string that contains ^ at the location to invoke the
  /// textDocument/implementations command and has ranges marked with
  /// `[[brackets]]` that are expected to be included (or not, if [shouldMatch]
  /// is set to `false`) in the results.
  Future<void> _testMarkedContent(String content,
      {bool shouldMatch = true}) async {
    await initialize();
    await openFile(mainFileUri, withoutMarkers(content));

    final res = await getImplementations(
      mainFileUri,
      positionFromMarker(content),
    );

    final expectedLocations = rangesFromMarkers(content)
        .map((r) => Location(uri: mainFileUri.toString(), range: r));

    if (shouldMatch) {
      expect(res, equals(expectedLocations));
    } else {
      expectedLocations.forEach((l) => expect(res, isNot(contains(res))));
    }
  }
}
