// 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:kernel/visitor.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');
    var A = new InterfaceType(classA, Nullability.legacy);
    var typedefF = new Typedef('F', A);
    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);
    }
  }
}
