// 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/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}) {
    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}) {
    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);
  }
}
