// Copyright (c) 2017, 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.

// @dart = 2.9

import 'package:front_end/src/fasta/type_inference/type_schema.dart';
import 'package:kernel/ast.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

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

typedef U _UnaryFunction<T, U>(T t);

@reflectiveTest
class UnknownTypeTest {
  static const unknownType = const UnknownType();

  void test_equality() {
    expect(unknownType, equals(unknownType));
    expect(unknownType, equals(new UnknownType()));
    expect(unknownType, isNot(equals(const DynamicType())));
  }

  void test_isKnown() {
    expect(isKnown(unknownType), isFalse);
    expect(isKnown(const DynamicType()), isTrue);
    var classA = new Class(name: 'A', fileUri: dummyUri);
    var A = new InterfaceType(classA, Nullability.legacy);
    var typedefF = new Typedef('F', A, fileUri: dummyUri);
    expect(isKnown(A), isTrue);
    expect(isKnown(new InterfaceType(classA, Nullability.legacy, [A])), isTrue);
    expect(
        isKnown(new InterfaceType(classA, Nullability.legacy, [unknownType])),
        isFalse);
    expect(isKnown(new FunctionType([], const VoidType(), Nullability.legacy)),
        isTrue);
    expect(isKnown(new FunctionType([], unknownType, Nullability.legacy)),
        isFalse);
    expect(isKnown(new FunctionType([A], const VoidType(), Nullability.legacy)),
        isTrue);
    expect(
        isKnown(new FunctionType(
            [unknownType], const VoidType(), Nullability.legacy)),
        isFalse);
    expect(
        isKnown(new FunctionType([], const VoidType(), Nullability.legacy,
            namedParameters: [new NamedType('x', A)])),
        isTrue);
    expect(
        isKnown(new FunctionType([], const VoidType(), Nullability.legacy,
            namedParameters: [new NamedType('x', unknownType)])),
        isFalse);
    expect(isKnown(new TypedefType(typedefF, Nullability.legacy)), isTrue);
    expect(isKnown(new TypedefType(typedefF, Nullability.legacy, [A])), isTrue);
    expect(
        isKnown(new TypedefType(typedefF, Nullability.legacy, [unknownType])),
        isFalse);
  }

  void test_ordinary_visitor_noOverrides() {
    expect(unknownType.accept(new _OrdinaryVisitor()), isNull);
  }

  void test_ordinary_visitor_overrideDefault() {
    expect(unknownType
        .accept(new _OrdinaryVisitor<String>(defaultDartType: (DartType node) {
      expect(node, same(unknownType));
      return 'defaultDartType';
    })), 'defaultDartType');
  }

  void test_type_schema_visitor_noOverrides() {
    expect(unknownType.accept(new _TypeSchemaVisitor()), isNull);
  }

  void test_type_schema_visitor_overrideDefault() {
    expect(unknownType.accept(
        new _TypeSchemaVisitor<String>(defaultDartType: (DartType node) {
      expect(node, same(unknownType));
      return 'defaultDartType';
    })), 'defaultDartType');
  }

  void test_type_schema_visitor_overrideVisitUnknownType() {
    expect(unknownType.accept(
        new _TypeSchemaVisitor<String>(visitUnknownType: (UnknownType node) {
      expect(node, same(unknownType));
      return 'visitUnknownType';
    })), 'visitUnknownType');
  }

  void test_typeSchemaToString() {
    expect(unknownType.toString(), isNot('?'));
    expect(typeSchemaToString(unknownType), '?');
    expect(
        typeSchemaToString(new FunctionType(
            [unknownType, unknownType], unknownType, Nullability.legacy)),
        '(?, ?) →* ?');
  }

  void test_visitChildren() {
    unknownType
        .visitChildren(new _TypeSchemaVisitor(defaultDartType: (DartType node) {
      fail('Should not have visited anything');
    }));
  }
}

class _OrdinaryVisitor<R> extends Visitor<R> with VisitorNullMixin<R> {
  final _UnaryFunction<DartType, R> _defaultDartType;

  _OrdinaryVisitor({_UnaryFunction<DartType, R> defaultDartType})
      : _defaultDartType = defaultDartType;

  @override
  R defaultDartType(DartType node) {
    if (_defaultDartType != null) {
      return _defaultDartType(node);
    } else {
      return super.defaultDartType(node);
    }
  }
}

class _TypeSchemaVisitor<R> extends Visitor<R> with VisitorNullMixin<R> {
  final _UnaryFunction<DartType, R> _defaultDartType;
  final _UnaryFunction<UnknownType, R> _visitUnknownType;

  _TypeSchemaVisitor(
      {_UnaryFunction<DartType, R> defaultDartType,
      _UnaryFunction<UnknownType, R> visitUnknownType})
      : _defaultDartType = defaultDartType,
        _visitUnknownType = visitUnknownType;

  @override
  R defaultDartType(DartType node) {
    if (node is UnknownType && _visitUnknownType != null) {
      return _visitUnknownType(node);
    } else if (_defaultDartType != null) {
      return _defaultDartType(node);
    } else {
      return super.defaultDartType(node);
    }
  }
}
