// 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/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/source.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/utilities_dart.dart';
import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/already_migrated_code_decorator.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/nullability_node_target.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'migration_visitor_test_base.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(_AlreadyMigratedCodeDecoratorTestNormal);
    defineReflectiveTests(_AlreadyMigratedCodeDecoratorTestProvisional);
  });
}

class _AlreadyMigratedCodeDecoratorTestBase extends Object with EdgeTester {
  final TypeProvider typeProvider;

  final AlreadyMigratedCodeDecorator decorator;

  final NullabilityGraphForTesting graph;

  final NullabilitySuffix suffix;

  Element element = _MockElement();

  final decoratedTypeParameterBounds = DecoratedTypeParameterBounds();

  _AlreadyMigratedCodeDecoratorTestBase(NullabilitySuffix nullabilitySuffix)
      : this._(
          nullabilitySuffix,
          NullabilityGraphForTesting(),
          TestTypeProvider(),
        );

  _AlreadyMigratedCodeDecoratorTestBase._(
      this.suffix, this.graph, this.typeProvider)
      : decorator =
            AlreadyMigratedCodeDecorator(graph, typeProvider, _getLineInfo);

  NullabilityNode get always => graph.always;

  NullabilityNode get never => graph.never;

  void checkAlwaysNullable(NullabilityNode node, String displayName) {
    var edge = assertEdge(always, node, hard: true, checkable: false);
    var origin = graph.getEdgeOrigin(edge)!;
    expect(origin.kind, EdgeOriginKind.alwaysNullableType);
    expect(origin.element, same(element));
    expect(node.displayName, displayName);
  }

  void checkDynamic(DecoratedType? decoratedType, String displayName) {
    expect(decoratedType!.type, same(typeProvider.dynamicType));
    checkAlwaysNullable(decoratedType.node!, displayName);
  }

  void checkExplicitlyNonNullable(NullabilityNode? node, String displayName) {
    var edge = assertEdge(node, never, hard: true, checkable: false);
    var origin = graph.getEdgeOrigin(edge)!;
    expect(origin.kind, EdgeOriginKind.alreadyMigratedType);
    expect(origin.element, same(element));
    expect(node!.displayName, displayName);
  }

  void checkExplicitlyNullable(NullabilityNode? node, String displayName) {
    var edge = assertEdge(always, node, hard: true, checkable: false);
    var origin = graph.getEdgeOrigin(edge)!;
    expect(origin.kind, EdgeOriginKind.alreadyMigratedType);
    expect(origin.element, same(element));
    expect(node!.displayName, displayName);
  }

  void checkFutureOr(
      DecoratedType decoratedType,
      void Function(NullabilityNode?, String) checkNullability,
      void Function(DecoratedType?, String) checkArgument,
      String displayName) {
    expect(decoratedType.type!.element, typeProvider.futureOrElement);
    checkNullability(decoratedType.node, displayName);
    checkArgument(
        decoratedType.typeArguments[0], 'type argument 0 of $displayName');
  }

  void checkInt(
      DecoratedType decoratedType,
      void Function(NullabilityNode?, String) checkNullability,
      String displayName) {
    expect(decoratedType.type!.element, typeProvider.intType.element);
    checkNullability(decoratedType.node, displayName);
  }

  void checkIterable(
      DecoratedType decoratedType,
      void Function(NullabilityNode?, String) checkNullability,
      void Function(DecoratedType?, String) checkArgument,
      String displayName) {
    expect(
        decoratedType.type!.element, typeProvider.iterableDynamicType.element);
    checkNullability(decoratedType.node, displayName);
    checkArgument(
        decoratedType.typeArguments[0], 'type argument 0 of $displayName');
  }

  void checkNever(DecoratedType decoratedType, String displayName) {
    expect(decoratedType.type, same(typeProvider.neverType));
    checkExplicitlyNonNullable(decoratedType.node, displayName);
  }

  void checkNum(
      DecoratedType decoratedType,
      void Function(NullabilityNode?, String) checkNullability,
      String displayName) {
    expect(decoratedType.type!.element, typeProvider.numType.element);
    checkNullability(decoratedType.node, displayName);
  }

  void checkObject(
      DecoratedType decoratedType,
      void Function(NullabilityNode?, String) checkNullability,
      String displayName) {
    expect(decoratedType.type!.element, typeProvider.objectType.element);
    checkNullability(decoratedType.node, displayName);
  }

  void checkTypeParameter(
      DecoratedType decoratedType,
      void Function(NullabilityNode?, String) checkNullability,
      TypeParameterElement expectedElement,
      String displayName) {
    var type = decoratedType.type as TypeParameterTypeImpl;
    expect(type.element, same(expectedElement));
    checkNullability(decoratedType.node, displayName);
  }

  void checkVoid(DecoratedType decoratedType, String displayName) {
    expect(decoratedType.type, same(typeProvider.voidType));
    checkAlwaysNullable(decoratedType.node!, displayName);
  }

  DecoratedType decorate(DartType type) {
    var decoratedType = decorator.decorate(
        type, element, NullabilityNodeTarget.text('test type'));
    expect(decoratedType.type, same(type));
    return decoratedType;
  }

  DecoratedType? getDecoratedBound(TypeParameterElement element) =>
      decoratedTypeParameterBounds.get(element);

  void setUp() {
    DecoratedTypeParameterBounds.current = decoratedTypeParameterBounds;
  }

  void tearDown() {
    DecoratedTypeParameterBounds.current = null;
  }

  void test_decorate_dynamic() {
    checkDynamic(decorate(typeProvider.dynamicType), 'test type');
  }

  void test_decorate_functionType_generic_bounded() {
    var typeFormal = element = TypeParameterElementImpl.synthetic('T')
      ..bound = typeProvider.numType;
    var decoratedType = decorate(
      FunctionTypeImpl(
        typeFormals: [typeFormal],
        parameters: const [],
        returnType: TypeParameterTypeImpl(
          element: typeFormal,
          nullabilitySuffix: NullabilitySuffix.star,
        ),
        nullabilitySuffix: suffix,
      ),
    );
    checkNum(getDecoratedBound(typeFormal)!, checkExplicitlyNonNullable,
        'bound of type formal T of test type');
    checkTypeParameter(decoratedType.returnType!, checkExplicitlyNonNullable,
        typeFormal, 'return type of test type');
  }

  void test_decorate_functionType_generic_no_explicit_bound() {
    var typeFormal = element = TypeParameterElementImpl.synthetic('T');
    var decoratedType = decorate(
      FunctionTypeImpl(
        typeFormals: [typeFormal],
        parameters: const [],
        returnType: TypeParameterTypeImpl(
          element: typeFormal,
          nullabilitySuffix: NullabilitySuffix.star,
        ),
        nullabilitySuffix: suffix,
      ),
    );
    checkObject(getDecoratedBound(typeFormal)!, checkExplicitlyNullable,
        'bound of type formal T of test type');
    checkTypeParameter(decoratedType.returnType!, checkExplicitlyNonNullable,
        typeFormal, 'return type of test type');
  }

  void test_decorate_functionType_named_parameter() {
    checkDynamic(
        decorate(
          FunctionTypeImpl(
            typeFormals: const [],
            parameters: [
              ParameterElementImpl.synthetic(
                'x',
                typeProvider.dynamicType,
                ParameterKind.NAMED,
              )
            ],
            returnType: typeProvider.voidType,
            nullabilitySuffix: suffix,
          ),
        ).namedParameters!['x'],
        'parameter x of test type');
  }

  void test_decorate_functionType_ordinary_parameters() {
    var decoratedType = decorate(
      FunctionTypeImpl(
        typeFormals: const [],
        parameters: [
          ParameterElementImpl.synthetic(
            'x',
            typeProvider.dynamicType,
            ParameterKind.REQUIRED,
          ),
          ParameterElementImpl.synthetic(
            'y',
            typeProvider.dynamicType,
            ParameterKind.REQUIRED,
          )
        ],
        returnType: typeProvider.voidType,
        nullabilitySuffix: suffix,
      ),
    );
    checkDynamic(
        decoratedType.positionalParameters![0], 'parameter 0 of test type');
    checkDynamic(
        decoratedType.positionalParameters![1], 'parameter 1 of test type');
  }

  void test_decorate_functionType_positional_parameter() {
    checkDynamic(
        decorate(
          FunctionTypeImpl(
            typeFormals: const [],
            parameters: [
              ParameterElementImpl.synthetic(
                'x',
                typeProvider.dynamicType,
                ParameterKind.POSITIONAL,
              )
            ],
            returnType: typeProvider.voidType,
            nullabilitySuffix: suffix,
          ),
        ).positionalParameters![0],
        'parameter 0 of test type');
  }

  void test_decorate_functionType_question() {
    checkExplicitlyNullable(
        decorate(
          FunctionTypeImpl(
            typeFormals: const [],
            parameters: const [],
            returnType: typeProvider.voidType,
            nullabilitySuffix: NullabilitySuffix.question,
          ),
        ).node,
        'test type');
  }

  void test_decorate_functionType_returnType() {
    checkDynamic(
        decorate(
          FunctionTypeImpl(
            typeFormals: const [],
            parameters: const [],
            returnType: typeProvider.dynamicType,
            nullabilitySuffix: suffix,
          ),
        ).returnType,
        'return type of test type');
  }

  void test_decorate_functionType_star() {
    checkExplicitlyNonNullable(
        decorate(
          FunctionTypeImpl(
            typeFormals: const [],
            parameters: const [],
            returnType: typeProvider.voidType,
            nullabilitySuffix: suffix,
          ),
        ).node,
        'test type');
  }

  void test_decorate_interfaceType_parameters() {
    var decoratedType = decorate(InterfaceTypeImpl(
        element: typeProvider.mapElement,
        typeArguments: [typeProvider.intType, typeProvider.numType],
        nullabilitySuffix: suffix));
    checkInt(decoratedType.typeArguments[0]!, checkExplicitlyNonNullable,
        'type argument 0 of test type');
    checkNum(decoratedType.typeArguments[1]!, checkExplicitlyNonNullable,
        'type argument 1 of test type');
  }

  void test_decorate_interfaceType_simple_question() {
    checkInt(
        decorate(
          InterfaceTypeImpl(
            element: typeProvider.intElement,
            typeArguments: const [],
            nullabilitySuffix: NullabilitySuffix.question,
          ),
        ),
        checkExplicitlyNullable,
        'test type');
  }

  void test_decorate_interfaceType_simple_star() {
    checkInt(
        decorate(
          InterfaceTypeImpl(
            element: typeProvider.intElement,
            typeArguments: const [],
            nullabilitySuffix: suffix,
          ),
        ),
        checkExplicitlyNonNullable,
        'test type');
  }

  void test_decorate_iterable_dynamic() {
    var decorated = decorate(typeProvider.iterableDynamicType);
    checkIterable(
        decorated, checkExplicitlyNonNullable, checkDynamic, 'test type');
  }

  void test_decorate_never() {
    checkNever(decorate(typeProvider.neverType), 'test type');
  }

  void test_decorate_typeParameterType_question() {
    var element = TypeParameterElementImpl.synthetic('T');
    checkTypeParameter(
        decorate(TypeParameterTypeImpl(
            element: element, nullabilitySuffix: NullabilitySuffix.question)),
        checkExplicitlyNullable,
        element,
        'test type');
  }

  void test_decorate_typeParameterType_star() {
    var element = TypeParameterElementImpl.synthetic('T');
    checkTypeParameter(
        decorate(
            TypeParameterTypeImpl(element: element, nullabilitySuffix: suffix)),
        checkExplicitlyNonNullable,
        element,
        'test type');
  }

  void test_decorate_void() {
    checkVoid(decorate(typeProvider.voidType), 'test type');
  }

  void test_getImmediateSupertypes_future() {
    var class_ = element = typeProvider.futureElement;
    var decoratedSupertypes = decorator.getImmediateSupertypes(class_).toList();
    var typeParam = class_.typeParameters[0];
    expect(decoratedSupertypes, hasLength(2));
    // Note: the bogus location `async:1:1` is because we're using a
    // TestTypeProvider.
    checkObject(decoratedSupertypes[0], checkExplicitlyNonNullable,
        'Future (async:1:1)');
    // Since Future<T> is a subtype of FutureOr<T>, we consider FutureOr<T> to
    // be an immediate supertype, even though the class declaration for Future
    // doesn't mention FutureOr.
    // Note: the bogus location `async:1:1` is because we're using a
    // TestTypeProvider.
    checkFutureOr(
        decoratedSupertypes[1],
        checkExplicitlyNonNullable,
        (t, displayName) => checkTypeParameter(
            t!, checkExplicitlyNonNullable, typeParam, displayName),
        'Future (async:1:1)');
  }

  void test_getImmediateSupertypes_generic() {
    var library = _LibraryElementMock();
    var t = ElementFactory.typeParameterElement('T');
    var class_ = element = ElementFactory.classElement3(
      name: 'C',
      typeParameters: [t],
      supertype: typeProvider.iterableType(
        t.instantiate(nullabilitySuffix: suffix),
      ),
    );
    class_.enclosingElement = library.definingCompilationUnit;
    var decoratedSupertypes = decorator.getImmediateSupertypes(class_).toList();
    expect(decoratedSupertypes, hasLength(1));
    checkIterable(
        decoratedSupertypes[0],
        checkExplicitlyNonNullable,
        (type, displayName) => checkTypeParameter(
            type!, checkExplicitlyNonNullable, t, displayName),
        'C (test.dart:1:1)');
  }

  void test_getImmediateSupertypes_interface() {
    var library = _LibraryElementMock();
    var class_ =
        element = ElementFactory.classElement('C', typeProvider.objectType);
    class_.interfaces = [typeProvider.numType];
    class_.enclosingElement = library.definingCompilationUnit;
    var decoratedSupertypes = decorator.getImmediateSupertypes(class_).toList();
    expect(decoratedSupertypes, hasLength(2));
    checkObject(decoratedSupertypes[0], checkExplicitlyNonNullable,
        'C (test.dart:1:1)');
    checkNum(decoratedSupertypes[1], checkExplicitlyNonNullable,
        'C (test.dart:1:1)');
  }

  void test_getImmediateSupertypes_mixin() {
    var library = _LibraryElementMock();
    var class_ =
        element = ElementFactory.classElement('C', typeProvider.objectType);
    class_.mixins = [typeProvider.numType];
    class_.enclosingElement = library.definingCompilationUnit;
    var decoratedSupertypes = decorator.getImmediateSupertypes(class_).toList();
    expect(decoratedSupertypes, hasLength(2));
    checkObject(decoratedSupertypes[0], checkExplicitlyNonNullable,
        'C (test.dart:1:1)');
    checkNum(decoratedSupertypes[1], checkExplicitlyNonNullable,
        'C (test.dart:1:1)');
  }

  void test_getImmediateSupertypes_superclassConstraint() {
    var library = _LibraryElementMock();
    var class_ = element = ElementFactory.mixinElement(
        name: 'C', constraints: [typeProvider.numType]);
    class_.enclosingElement = library.definingCompilationUnit;
    var decoratedSupertypes = decorator.getImmediateSupertypes(class_).toList();
    expect(decoratedSupertypes, hasLength(1));
    checkNum(decoratedSupertypes[0], checkExplicitlyNonNullable,
        'C (test.dart:1:1)');
  }

  void test_getImmediateSupertypes_supertype() {
    var library = _LibraryElementMock();
    var class_ =
        element = ElementFactory.classElement('C', typeProvider.objectType);
    class_.enclosingElement = library.definingCompilationUnit;
    var decoratedSupertypes = decorator.getImmediateSupertypes(class_).toList();
    expect(decoratedSupertypes, hasLength(1));
    // TODO(paulberry): displayName should be 'Object supertype of C'
    checkObject(decoratedSupertypes[0], checkExplicitlyNonNullable,
        'C (test.dart:1:1)');
  }

  static LineInfo _getLineInfo(String path) => LineInfo([0]);
}

/// Specialization of [_AlreadyMigratedCodeDecoratorTestBase] for testing the
/// situation where the already migrated code does not contain star types.  In
/// the final product, by definition all already-migrated code will be free of
/// star types.  However, since we do not yet migrate using a fully NNBD-aware
/// SDK, we need to handle both star and non-star variants on a short term
/// basis.
@reflectiveTest
class _AlreadyMigratedCodeDecoratorTestNormal
    extends _AlreadyMigratedCodeDecoratorTestBase {
  _AlreadyMigratedCodeDecoratorTestNormal() : super(NullabilitySuffix.none);
}

/// Specialization of [_AlreadyMigratedCodeDecoratorTestBase] for testing the
/// situation where the already migrated code contains star types.  In the final
/// product, this will never happen.  However, since we do not yet migrate using
/// a fully NNBD-aware SDK, we need to handle both star and non-star variants on
/// a short term basis.
@reflectiveTest
class _AlreadyMigratedCodeDecoratorTestProvisional
    extends _AlreadyMigratedCodeDecoratorTestBase {
  _AlreadyMigratedCodeDecoratorTestProvisional()
      : super(NullabilitySuffix.star);
}

class _CompilationUnitElementMock implements CompilationUnitElementImpl {
  @override
  final LibraryElement enclosingElement;

  @override
  final Source source;

  _CompilationUnitElementMock(this.enclosingElement, this.source);

  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class _LibraryElementMock implements LibraryElementImpl {
  @override
  late CompilationUnitElement definingCompilationUnit;

  @override
  late Source source;

  _LibraryElementMock() {
    source = _SourceMock();
    definingCompilationUnit = _CompilationUnitElementMock(this, source);
  }

  @override
  Element? get enclosingElement => null;

  @override
  bool get isNonNullableByDefault => false;

  @override
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class _MockElement implements Element {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class _SourceMock implements Source {
  String get fullName => '/test.dart';

  @override
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
