// Copyright (c) 2020, 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/null_safety_understanding_flag.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../../generated/type_system_test.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ReplaceTopBottomLegacyTest);
    defineReflectiveTests(ReplaceTopBottomNullSafetyTest);
  });
}

@reflectiveTest
class ReplaceTopBottomLegacyTest extends AbstractTypeSystemTest {
  test_contravariant_bottom() {
    // Not contravariant.
    _check(nullStar, 'Null*');

    _check(
      functionTypeStar(returnType: intStar, parameters: [
        requiredParameter(type: nullStar),
      ]),
      'int* Function(dynamic)*',
    );
  }

  test_covariant_top() {
    _check(objectStar, 'Null*');
    _check(dynamicNone, 'Null*');
    _check(voidNone, 'Null*');

    _check(listStar(objectStar), 'List<Null*>*');
    _check(listStar(dynamicNone), 'List<Null*>*');
    _check(listStar(voidNone), 'List<Null*>*');

    _check(futureOrStar(objectStar), 'Null*');
    _check(futureOrStar(dynamicNone), 'Null*');
    _check(futureOrStar(voidNone), 'Null*');
    _check(futureOrStar(futureOrStar(voidNone)), 'Null*');

    _check(
      functionTypeStar(returnType: intStar, parameters: [
        requiredParameter(
          type: functionTypeStar(returnType: intStar, parameters: [
            requiredParameter(type: objectStar),
          ]),
        ),
      ]),
      'int* Function(int* Function(Null*)*)*',
      typeStr: 'int* Function(int* Function(Object*)*)*',
    );

    _check(intStar, 'int*');
    _check(listStar(intStar), 'List<int*>*');
  }

  void _check(DartType type, String expectedStr, {String? typeStr}) {
    NullSafetyUnderstandingFlag.enableNullSafetyTypes(() {
      if (typeStr != null) {
        expect(_typeString(type), typeStr);
      }

      var result = typeSystem.replaceTopAndBottom(type);
      var resultStr = _typeString(result);
      expect(resultStr, expectedStr);
    });
  }

  String _typeString(DartType type) {
    return type.getDisplayString(withNullability: true);
  }
}

@reflectiveTest
class ReplaceTopBottomNullSafetyTest extends AbstractTypeSystemNullSafetyTest {
  test_contravariant_bottom() {
    // Not contravariant.
    _check(neverNone, 'Never');

    void checkContravariant(DartType type, String expectedStr) {
      _check(
        functionTypeNone(returnType: intNone, parameters: [
          requiredParameter(type: type),
        ]),
        'int Function($expectedStr)',
      );
    }

    checkContravariant(neverNone, 'Object?');

    checkContravariant(
      typeParameterTypeNone(
        typeParameter('T', bound: neverNone),
      ),
      'Object?',
    );
  }

  test_notContravariant_covariant_top() {
    _check(objectQuestion, 'Never');
    _check(objectStar, 'Never');
    _check(dynamicNone, 'Never');
    _check(voidNone, 'Never');

    _check(listNone(objectQuestion), 'List<Never>');
    _check(listNone(objectStar), 'List<Never>');
    _check(listNone(dynamicNone), 'List<Never>');
    _check(listNone(voidNone), 'List<Never>');

    _check(futureOrNone(objectQuestion), 'Never');
    _check(futureOrNone(objectStar), 'Never');
    _check(futureOrNone(dynamicNone), 'Never');
    _check(futureOrNone(voidNone), 'Never');
    _check(futureOrNone(futureOrNone(voidNone)), 'Never');

    _check(
      functionTypeNone(returnType: intNone, parameters: [
        requiredParameter(
          type: functionTypeNone(returnType: intNone, parameters: [
            requiredParameter(type: objectQuestion),
          ]),
        ),
      ]),
      'int Function(int Function(Never))',
      typeStr: 'int Function(int Function(Object?))',
    );

    _check(intNone, 'int');
    _check(intQuestion, 'int?');

    _check(listNone(intNone), 'List<int>');
    _check(listNone(intQuestion), 'List<int?>');
    _check(listQuestion(intNone), 'List<int>?');
    _check(listQuestion(intQuestion), 'List<int?>?');
  }

  test_notContravariant_invariant() {
    // typedef F<T> = T Function(T);
    var T = typeParameter('T', variance: Variance.invariant);
    var T_none = typeParameterTypeNone(T);
    var F = typeAlias(
      name: 'F',
      typeParameters: [T],
      aliasedType: functionTypeNone(
        returnType: T_none,
        parameters: [requiredParameter(type: T_none)],
      ),
    );

    var F_dynamic = F.instantiate(
      typeArguments: [dynamicNone],
      nullabilitySuffix: NullabilitySuffix.none,
    );
    _check(F_dynamic, 'Never Function(Never)');
  }

  void _check(DartType type, String expectedStr, {String? typeStr}) {
    NullSafetyUnderstandingFlag.enableNullSafetyTypes(() {
      if (typeStr != null) {
        expect(_typeString(type), typeStr);
      }

      var result = typeSystem.replaceTopAndBottom(type);
      var resultStr = _typeString(result);
      expect(resultStr, expectedStr);
    });
  }

  String _typeString(DartType type) {
    return type.getDisplayString(withNullability: true);
  }
}
