// 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:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/type_system.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../../generated/elements_types_mixin.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(InterfaceLeastUpperBoundHelperTest);
  });
}

@reflectiveTest
class InterfaceLeastUpperBoundHelperTest with ElementsTypesMixin {
  final TestTypeProvider typeProvider = TestTypeProvider();

  void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
    //
    //   Object
    //     |
    //     A
    //    / \
    //   B   C
    //   |   |
    //   |   D
    //    \ /
    //     E
    //
    ClassElementImpl classA = ElementFactory.classElement2("A");
    ClassElementImpl classB = ElementFactory.classElement2("B");
    ClassElementImpl classC = ElementFactory.classElement2("C");
    ClassElementImpl classD = ElementFactory.classElement2("D");
    ClassElementImpl classE = ElementFactory.classElement2("E");
    classB.interfaces = <InterfaceType>[interfaceType(classA)];
    classC.interfaces = <InterfaceType>[interfaceType(classA)];
    classD.interfaces = <InterfaceType>[interfaceType(classC)];
    classE.interfaces = <InterfaceType>[
      interfaceType(classB),
      interfaceType(classD)
    ];
    // assertion: even though the longest path to Object for typeB is 2, and
    // typeE implements typeB, the longest path for typeE is 4 since it also
    // implements typeD
    expect(_longestPathToObject(classB), 2);
    expect(_longestPathToObject(classE), 4);
  }

  void test_computeLongestInheritancePathToObject_multipleSuperclassPaths() {
    //
    //   Object
    //     |
    //     A
    //    / \
    //   B   C
    //   |   |
    //   |   D
    //    \ /
    //     E
    //
    ClassElement classA = ElementFactory.classElement2("A");
    ClassElement classB =
        ElementFactory.classElement("B", interfaceType(classA));
    ClassElement classC =
        ElementFactory.classElement("C", interfaceType(classA));
    ClassElement classD =
        ElementFactory.classElement("D", interfaceType(classC));
    ClassElementImpl classE =
        ElementFactory.classElement("E", interfaceType(classB));
    classE.interfaces = <InterfaceType>[interfaceType(classD)];
    // assertion: even though the longest path to Object for typeB is 2, and
    // typeE extends typeB, the longest path for typeE is 4 since it also
    // implements typeD
    expect(_longestPathToObject(classB), 2);
    expect(_longestPathToObject(classE), 4);
  }

  void test_computeLongestInheritancePathToObject_object() {
    expect(_longestPathToObject(typeProvider.objectType.element), 0);
  }

  void test_computeLongestInheritancePathToObject_recursion() {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    ClassElementImpl classB =
        ElementFactory.classElement("B", interfaceType(classA));
    classA.supertype = interfaceType(classB);
    expect(_longestPathToObject(classA), 2);
  }

  void test_computeLongestInheritancePathToObject_singleInterfacePath() {
    //
    //   Object
    //     |
    //     A
    //     |
    //     B
    //     |
    //     C
    //
    ClassElementImpl classA = ElementFactory.classElement2("A");
    ClassElementImpl classB = ElementFactory.classElement2("B");
    ClassElementImpl classC = ElementFactory.classElement2("C");
    classB.interfaces = <InterfaceType>[interfaceType(classA)];
    classC.interfaces = <InterfaceType>[interfaceType(classB)];
    expect(_longestPathToObject(classA), 1);
    expect(_longestPathToObject(classB), 2);
    expect(_longestPathToObject(classC), 3);
  }

  void test_computeLongestInheritancePathToObject_singleSuperclassPath() {
    //
    //   Object
    //     |
    //     A
    //     |
    //     B
    //     |
    //     C
    //
    ClassElement classA = ElementFactory.classElement2("A");
    ClassElement classB =
        ElementFactory.classElement("B", interfaceType(classA));
    ClassElement classC =
        ElementFactory.classElement("C", interfaceType(classB));
    expect(_longestPathToObject(classA), 1);
    expect(_longestPathToObject(classB), 2);
    expect(_longestPathToObject(classC), 3);
  }

  void test_computeSuperinterfaceSet_genericInterfacePath() {
    //
    //  A
    //  | implements
    //  B<T>
    //  | implements
    //  C<T>
    //
    //  D
    //

    var instObject = InstantiatedClass.of(typeProvider.objectType);

    ClassElementImpl classA = class_(name: 'A');
    var instA = InstantiatedClass(classA, const []);

    var BT = typeParameter('T');
    var classB = class_(
      name: 'B',
      typeParameters: [BT],
      interfaces: [instA.withNullabilitySuffixNone],
    );

    var CT = typeParameter('T');
    var classC = class_(
      name: 'C',
      typeParameters: [CT],
      interfaces: [
        InstantiatedClass(
          classB,
          [typeParameterType(CT)],
        ).withNullabilitySuffixNone,
      ],
    );

    var classD = class_(name: 'D');

    // A
    expect(
      _superInterfaces(instA),
      unorderedEquals([instObject]),
    );

    // B<D>
    expect(
      _superInterfaces(
        InstantiatedClass(classB, [interfaceType(classD)]),
      ),
      unorderedEquals([instObject, instA]),
    );

    // C<D>
    expect(
      _superInterfaces(
        InstantiatedClass(classC, [interfaceType(classD)]),
      ),
      unorderedEquals([
        instObject,
        instA,
        InstantiatedClass(classB, [interfaceType(classD)]),
      ]),
    );
  }

  void test_computeSuperinterfaceSet_genericSuperclassPath() {
    //
    //  A
    //  |
    //  B<T>
    //  |
    //  C<T>
    //
    //  D
    //

    var instObject = InstantiatedClass.of(typeProvider.objectType);

    ClassElementImpl classA = ElementFactory.classElement2('A');
    var instA = InstantiatedClass(classA, const []);

    var classB = ElementFactory.classElement3(
      name: 'B',
      typeParameterNames: ['T'],
      supertype: instA.withNullabilitySuffixNone,
    );

    var typeParametersC = ElementFactory.typeParameters(['T']);
    var classC = ElementFactory.classElement3(
      name: 'B',
      typeParameters: typeParametersC,
      supertype: InstantiatedClass(
        classB,
        [typeParameterType(typeParametersC[0])],
      ).withNullabilitySuffixNone,
    );

    var classD = ElementFactory.classElement2('D');

    // A
    expect(
      _superInterfaces(instA),
      unorderedEquals([instObject]),
    );

    // B<D>
    expect(
      _superInterfaces(
        InstantiatedClass(classB, [interfaceType(classD)]),
      ),
      unorderedEquals([instObject, instA]),
    );

    // C<D>
    expect(
      _superInterfaces(
        InstantiatedClass(classC, [interfaceType(classD)]),
      ),
      unorderedEquals([
        instObject,
        instA,
        InstantiatedClass(classB, [interfaceType(classD)]),
      ]),
    );
  }

  void test_computeSuperinterfaceSet_mixin_constraints() {
    var instObject = InstantiatedClass.of(typeProvider.objectType);

    var classA = ElementFactory.classElement3(name: 'A');
    var instA = InstantiatedClass(classA, const []);

    var classB = ElementFactory.classElement3(
      name: 'B',
      interfaces: [instA.withNullabilitySuffixNone],
    );
    var instB = InstantiatedClass(classB, const []);

    var classC = ElementFactory.classElement3(name: 'C');
    var instC = InstantiatedClass(classC, const []);

    var mixinM = ElementFactory.mixinElement(
      name: 'M',
      constraints: [
        instB.withNullabilitySuffixNone,
        instC.withNullabilitySuffixNone,
      ],
    );
    var instM = InstantiatedClass(mixinM, const []);

    expect(
      _superInterfaces(instM),
      unorderedEquals([instObject, instA, instB, instC]),
    );
  }

  void test_computeSuperinterfaceSet_mixin_constraints_object() {
    var instObject = InstantiatedClass.of(typeProvider.objectType);

    var mixinM = ElementFactory.mixinElement(name: 'M');
    var instM = InstantiatedClass(mixinM, const []);

    expect(
      _superInterfaces(instM),
      unorderedEquals([instObject]),
    );
  }

  void test_computeSuperinterfaceSet_mixin_interfaces() {
    var instObject = InstantiatedClass.of(typeProvider.objectType);

    var classA = ElementFactory.classElement3(name: 'A');
    var instA = InstantiatedClass(classA, const []);

    var classB = ElementFactory.classElement3(
      name: 'B',
      interfaces: [instA.withNullabilitySuffixNone],
    );
    var instB = InstantiatedClass(classB, const []);

    var classC = ElementFactory.classElement3(name: 'C');
    var instC = InstantiatedClass(classC, const []);

    var mixinM = ElementFactory.mixinElement(
      name: 'M',
      interfaces: [
        instB.withNullabilitySuffixNone,
        instC.withNullabilitySuffixNone,
      ],
    );
    var instM = InstantiatedClass(mixinM, const []);

    expect(
      _superInterfaces(instM),
      unorderedEquals([instObject, instA, instB, instC]),
    );
  }

  void test_computeSuperinterfaceSet_multipleInterfacePaths() {
    var instObject = InstantiatedClass.of(typeProvider.objectType);

    var classA = ElementFactory.classElement3(name: 'A');
    var instA = InstantiatedClass(classA, const []);

    var classB = ElementFactory.classElement3(
      name: 'B',
      interfaces: [instA.withNullabilitySuffixNone],
    );
    var instB = InstantiatedClass(classB, const []);

    var classC = ElementFactory.classElement3(
      name: 'C',
      interfaces: [instA.withNullabilitySuffixNone],
    );
    var instC = InstantiatedClass(classC, const []);

    var classD = ElementFactory.classElement3(
      name: 'D',
      interfaces: [instC.withNullabilitySuffixNone],
    );
    var instD = InstantiatedClass(classD, const []);

    var classE = ElementFactory.classElement3(
      name: 'E',
      interfaces: [
        instB.withNullabilitySuffixNone,
        instD.withNullabilitySuffixNone,
      ],
    );
    var instE = InstantiatedClass(classE, const []);

    // D
    expect(
      _superInterfaces(instD),
      unorderedEquals([instObject, instA, instC]),
    );

    // E
    expect(
      _superInterfaces(instE),
      unorderedEquals([instObject, instA, instB, instC, instD]),
    );
  }

  void test_computeSuperinterfaceSet_multipleSuperclassPaths() {
    var instObject = InstantiatedClass.of(typeProvider.objectType);

    var classA = ElementFactory.classElement3(name: 'A');
    var instA = InstantiatedClass(classA, const []);

    var classB = ElementFactory.classElement3(
      name: 'B',
      supertype: instA.withNullabilitySuffixNone,
    );
    var instB = InstantiatedClass(classB, const []);

    var classC = ElementFactory.classElement3(
      name: 'C',
      supertype: instA.withNullabilitySuffixNone,
    );
    var instC = InstantiatedClass(classC, const []);

    var classD = ElementFactory.classElement3(
      name: 'D',
      supertype: instC.withNullabilitySuffixNone,
    );
    var instD = InstantiatedClass(classD, const []);

    var classE = ElementFactory.classElement3(
      name: 'E',
      supertype: instB.withNullabilitySuffixNone,
      interfaces: [
        instD.withNullabilitySuffixNone,
      ],
    );
    var instE = InstantiatedClass(classE, const []);

    // D
    expect(
      _superInterfaces(instD),
      unorderedEquals([instObject, instA, instC]),
    );

    // E
    expect(
      _superInterfaces(instE),
      unorderedEquals([instObject, instA, instB, instC, instD]),
    );
  }

  void test_computeSuperinterfaceSet_recursion() {
    var classA = ElementFactory.classElement3(name: 'A');
    var instA = InstantiatedClass(classA, const []);

    var classB = ElementFactory.classElement3(
      name: 'B',
      supertype: instA.withNullabilitySuffixNone,
    );
    var instB = InstantiatedClass(classB, const []);

    classA.supertype = instB.withNullabilitySuffixNone;

    expect(
      _superInterfaces(instB),
      unorderedEquals([instA, instB]),
    );

    expect(
      _superInterfaces(instA),
      unorderedEquals([instA, instB]),
    );
  }

  void test_computeSuperinterfaceSet_singleInterfacePath() {
    var instObject = InstantiatedClass.of(typeProvider.objectType);

    var classA = ElementFactory.classElement3(name: 'A');
    var instA = InstantiatedClass(classA, const []);

    var classB = ElementFactory.classElement3(
      name: 'B',
      interfaces: [instA.withNullabilitySuffixNone],
    );
    var instB = InstantiatedClass(classB, const []);

    var classC = ElementFactory.classElement3(
      name: 'C',
      interfaces: [instB.withNullabilitySuffixNone],
    );
    var instC = InstantiatedClass(classC, const []);

    // A
    expect(
      _superInterfaces(instA),
      unorderedEquals([instObject]),
    );

    // B
    expect(
      _superInterfaces(instB),
      unorderedEquals([instObject, instA]),
    );

    // C
    expect(
      _superInterfaces(instC),
      unorderedEquals([instObject, instA, instB]),
    );
  }

  void test_computeSuperinterfaceSet_singleSuperclassPath() {
    //
    //  A
    //  |
    //  B
    //  |
    //  C
    //
    var instObject = InstantiatedClass.of(typeProvider.objectType);

    var classA = ElementFactory.classElement3(name: 'A');
    var instA = InstantiatedClass(classA, const []);

    var classB = ElementFactory.classElement3(
      name: 'B',
      supertype: instA.withNullabilitySuffixNone,
    );
    var instB = InstantiatedClass(classB, const []);

    var classC = ElementFactory.classElement3(
      name: 'C',
      supertype: instB.withNullabilitySuffixNone,
    );
    var instC = InstantiatedClass(classC, const []);

    // A
    expect(
      _superInterfaces(instA),
      unorderedEquals([instObject]),
    );

    // B
    expect(
      _superInterfaces(instB),
      unorderedEquals([instObject, instA]),
    );

    // C
    expect(
      _superInterfaces(instC),
      unorderedEquals([instObject, instA, instB]),
    );
  }

  int _longestPathToObject(ClassElement element) {
    return InterfaceLeastUpperBoundHelper.computeLongestInheritancePathToObject(
        element);
  }

  Set<InstantiatedClass> _superInterfaces(InstantiatedClass type) {
    return InterfaceLeastUpperBoundHelper.computeSuperinterfaceSet(type);
  }
}
