// Copyright (c) 2024, 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:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'dartdoc_test_base.dart';
import 'src/utils.dart';

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

@reflectiveTest
class ClassesTest extends DartdocTestBase {
  @override
  String get libraryName => 'classes';

  void test_availableExtensions_onClass() async {
    var library = await bootPackageWithLibrary('''
class C {}
extension Ex on C {}
''');

    var c = library.classes.named('C');
    expect(
      c.potentiallyApplicableExtensionsSorted,
      contains(library.extensions.named('Ex')),
    );
  }

  void test_availableExtensions_onClassWithInstantiatedType() async {
    var library = await bootPackageWithLibrary('''
class C<T> {}
extension Ex on C<int> {}
''');

    var c = library.classes.named('C');
    expect(
      c.potentiallyApplicableExtensionsSorted,
      contains(library.extensions.named('Ex')),
    );
  }

  void test_availableExtensions_onSubtypeOfClass() async {
    var library = await bootPackageWithLibrary('''
class C {}
class D extends C {}
extension Ex on C {}
''');

    var d = library.classes.named('D');
    expect(
      d.potentiallyApplicableExtensionsSorted,
      contains(library.extensions.named('Ex')),
    );
  }

  void test_availableExtensions_onInstantiatedSubtypeOfClass() async {
    var library = await bootPackageWithLibrary('''
class C<T> {}
class D<T> extends C<T> {}
extension Ex on C<int> {}
''');

    var d = library.classes.named('D');
    expect(
      d.potentiallyApplicableExtensionsSorted,
      contains(library.extensions.named('Ex')),
    );
  }

  void test_publicInterfaces_direct() async {
    var library = await bootPackageWithLibrary('''
class A {}
class B implements A {}
''');

    var b = library.classes.named('B');
    expect(b.publicInterfaces, hasLength(1));
    expect(b.publicInterfaces.first.modelElement, library.classes.named('A'));
  }

  void test_publicInterfaces_indirect() async {
    var library = await bootPackageWithLibrary('''
class A {}
class B implements A {}
class C implements B {}
''');

    var c = library.classes.named('C');
    // Only `B` is shown, not indirect-through-public like `A`.
    expect(c.publicInterfaces, hasLength(1));
    expect(c.publicInterfaces.first.modelElement, library.classes.named('B'));
  }

  void test_publicInterfaces_indirectViaPrivate() async {
    var library = await bootPackageWithLibrary('''
class A {}
class _B implements A {}
class C implements _B {}
''');

    var c = library.classes.named('C');
    expect(c.publicInterfaces, hasLength(1));
    expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
  }

  void test_publicInterfaces_indirectViaPrivate2() async {
    var library = await bootPackageWithLibrary('''
class A {}
class _B implements A {}
class _C implements _B {}
class D implements _C {}
''');

    var d = library.classes.named('D');
    expect(d.publicInterfaces, hasLength(1));
    expect(d.publicInterfaces.first.modelElement, library.classes.named('A'));
  }

  void test_publicInterfaces_indirectViaPrivateExtendedClass() async {
    var library = await bootPackageWithLibrary('''
class A {}
class _B implements A {}
class C extends _B {}
''');

    var c = library.classes.named('C');
    expect(c.publicInterfaces, hasLength(1));
    expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
  }

  void test_publicInterfaces_indirectViaPrivateExtendedClass2() async {
    var library = await bootPackageWithLibrary('''
class A {}
class _B implements A {}
class _C extends _B {}
class D extends _C {}
''');

    var c = library.classes.named('D');
    expect(c.publicInterfaces, hasLength(1));
    expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
  }

  void test_publicInterfaces_onlyExtendedClasses() async {
    var library = await bootPackageWithLibrary('''
class A {}
class B extends A {}
class _C extends B {}
class D extends _C {}
''');

    expect(library.classes.named('D').publicInterfaces, isEmpty);
  }

  void test_publicInterfaces_indirectViaPrivateMixedInMixin() async {
    var library = await bootPackageWithLibrary('''
class A {}
mixin _M implements A {}
class C with _M {}
''');

    var c = library.classes.named('C');
    expect(c.publicInterfaces, hasLength(1));
    expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
  }

  void test_publicInterfaces_indirectViaPrivate_multiply() async {
    var library = await bootPackageWithLibrary('''
class A<T> {}
class _B<U> implements A<U> {}
class C<T> implements A<T>, _B<T> {}
''');

    var c = library.classes.named('C');
    expect(c.publicInterfaces, hasLength(1));
    expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
  }

  void test_inheritanceOfObjectInstanceMethod() async {
    // This code is written such that `Inheritable._inheritance` for
    // `A.toString()` includes two copies of Object; one from walking up B's
    // chain, and then the second from walking up C's chain.
    var library = await bootPackageWithLibrary('''
class A implements B, C {}
class B implements C {}
class C implements D {}
class D implements Object {}
''');

    var toString = library.classes.named('A').instanceMethods.named('toString');
    expect(toString.canonicalEnclosingContainer!.isDartCoreObject, isTrue);
  }

  // TODO(srawlins): Test everything else about classes.
}
