// 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/ast/ast.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'migration_visitor_test_base.dart';

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

@reflectiveTest
class DecoratedClassHierarchyTest extends MigrationVisitorTestBase {
  late DecoratedClassHierarchy _hierarchy;

  @override
  Future<CompilationUnit> analyze(String code) async {
    var unit = await super.analyze(code);
    _hierarchy = DecoratedClassHierarchy(variables, graph);
    return unit;
  }

  Future<void> test_asInstanceOf_complex() async {
    await analyze('''
class Base<T> {}
class Derived<U> extends Base<List<U>> {}
Derived<int> x;
''');
    var decoratedType = decoratedTypeAnnotation('Derived<int>');
    var asInstanceOfBase =
        _hierarchy.asInstanceOf(decoratedType, findElement.class_('Base'));
    _assertType(asInstanceOfBase.type!, 'Base<List<int>>');
    expect(asInstanceOfBase.node, same(decoratedType.node));
    var listOfUType = decoratedTypeAnnotation('List<U>');
    expect(asInstanceOfBase.typeArguments[0]!.node, same(listOfUType.node));
    var substitution = asInstanceOfBase.typeArguments[0]!.typeArguments[0]!.node
        as NullabilityNodeForSubstitution;
    expect(substitution.innerNode, same(decoratedType.typeArguments[0]!.node));
    expect(substitution.outerNode, same(listOfUType.typeArguments[0]!.node));
  }

  Future<void> test_getDecoratedSupertype_complex() async {
    await analyze('''
class Base<T> {}
class Intermediate<U> extends Base<List<U>> {}
class Derived<V> extends Intermediate<Map<int, V>> {}
''');
    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
        findElement.class_('Derived'), findElement.class_('Base'));
    var listRef = decoratedTypeAnnotation('List');
    var uRef = decoratedTypeAnnotation('U>>');
    var mapRef = decoratedTypeAnnotation('Map');
    var intRef = decoratedTypeAnnotation('int');
    var vRef = decoratedTypeAnnotation('V>>');
    _assertType(decoratedSupertype.type!, 'Base<List<Map<int, V>>>');
    expect(decoratedSupertype.node, same(never));
    var baseArgs = decoratedSupertype.typeArguments;
    expect(baseArgs, hasLength(1));
    _assertType(baseArgs[0]!.type!, 'List<Map<int, V>>');
    expect(baseArgs[0]!.node, same(listRef.node));
    var listArgs = baseArgs[0]!.typeArguments;
    expect(listArgs, hasLength(1));
    _assertType(listArgs[0]!.type!, 'Map<int, V>');
    var mapNode = listArgs[0]!.node as NullabilityNodeForSubstitution;
    expect(mapNode.innerNode, same(mapRef.node));
    expect(mapNode.outerNode, same(uRef.node));
    var mapArgs = listArgs[0]!.typeArguments;
    expect(mapArgs, hasLength(2));
    _assertType(mapArgs[0]!.type!, 'int');
    expect(mapArgs[0]!.node, same(intRef.node));
    _assertType(mapArgs[1]!.type!, 'V');
    expect(mapArgs[1]!.node, same(vRef.node));
  }

  Future<void> test_getDecoratedSupertype_extends_simple() async {
    await analyze('''
class Base<T, U> {}
class Derived<V, W> extends Base<V, W> {}
''');
    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
        findElement.class_('Derived'), findElement.class_('Base'));
    var vRef = decoratedTypeAnnotation('V, W> {');
    var wRef = decoratedTypeAnnotation('W> {');
    _assertType(decoratedSupertype.type!, 'Base<V, W>');
    expect(decoratedSupertype.node, same(never));
    expect(decoratedSupertype.typeArguments, hasLength(2));
    _assertType(decoratedSupertype.typeArguments[0]!.type!, 'V');
    expect(decoratedSupertype.typeArguments[0]!.node, same(vRef.node));
    _assertType(decoratedSupertype.typeArguments[1]!.type!, 'W');
    expect(decoratedSupertype.typeArguments[1]!.node, same(wRef.node));
  }

  Future<void> test_getDecoratedSupertype_implements_simple() async {
    await analyze('''
class Base<T, U> {}
class Derived<V, W> implements Base<V, W> {}
''');
    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
        findElement.class_('Derived'), findElement.class_('Base'));
    var vRef = decoratedTypeAnnotation('V, W> {');
    var wRef = decoratedTypeAnnotation('W> {');
    _assertType(decoratedSupertype.type!, 'Base<V, W>');
    expect(decoratedSupertype.node, same(never));
    expect(decoratedSupertype.typeArguments, hasLength(2));
    _assertType(decoratedSupertype.typeArguments[0]!.type!, 'V');
    expect(decoratedSupertype.typeArguments[0]!.node, same(vRef.node));
    _assertType(decoratedSupertype.typeArguments[1]!.type!, 'W');
    expect(decoratedSupertype.typeArguments[1]!.node, same(wRef.node));
  }

  Future<void> test_getDecoratedSupertype_not_generic() async {
    await analyze('''
class Base {}
class Derived<T> extends Base {}
''');
    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
        findElement.class_('Derived'), findElement.class_('Base'));
    _assertType(decoratedSupertype.type!, 'Base');
    expect(decoratedSupertype.node, same(never));
    expect(decoratedSupertype.typeArguments, isEmpty);
  }

  Future<void> test_getDecoratedSupertype_on_simple() async {
    await analyze('''
class Base<T, U> {}
mixin Derived<V, W> on Base<V, W> {}
''');
    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
        findElement.mixin('Derived'), findElement.class_('Base'));
    var vRef = decoratedTypeAnnotation('V, W> {');
    var wRef = decoratedTypeAnnotation('W> {');
    _assertType(decoratedSupertype.type!, 'Base<V, W>');
    expect(decoratedSupertype.node, same(never));
    expect(decoratedSupertype.typeArguments, hasLength(2));
    _assertType(decoratedSupertype.typeArguments[0]!.type!, 'V');
    expect(decoratedSupertype.typeArguments[0]!.node, same(vRef.node));
    _assertType(decoratedSupertype.typeArguments[1]!.type!, 'W');
    expect(decoratedSupertype.typeArguments[1]!.node, same(wRef.node));
  }

  Future<void> test_getDecoratedSupertype_unrelated_type() async {
    await analyze('''
class A<T> {}
class B<T> {}
''');
    expect(
        () => _hierarchy.getDecoratedSupertype(
            findElement.class_('A'), findElement.class_('B')),
        throwsA(TypeMatcher<StateError>()));
  }

  Future<void> test_getDecoratedSupertype_with_simple() async {
    await analyze('''
class Base<T, U> {}
class Derived<V, W> extends Object with Base<V, W> {}
''');
    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
        findElement.class_('Derived'), findElement.class_('Base'));
    var vRef = decoratedTypeAnnotation('V, W> {');
    var wRef = decoratedTypeAnnotation('W> {');
    _assertType(decoratedSupertype.type!, 'Base<V, W>');
    expect(decoratedSupertype.node, same(never));
    expect(decoratedSupertype.typeArguments, hasLength(2));
    _assertType(decoratedSupertype.typeArguments[0]!.type!, 'V');
    expect(decoratedSupertype.typeArguments[0]!.node, same(vRef.node));
    _assertType(decoratedSupertype.typeArguments[1]!.type!, 'W');
    expect(decoratedSupertype.typeArguments[1]!.node, same(wRef.node));
  }

  void _assertType(DartType type, String expected) {
    var typeStr = type.getDisplayString(withNullability: false);
    expect(typeStr, expected);
  }
}
