// 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.

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