// 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:expect/expect.dart';

class Fields<T> {
  late T x;
  late T _y;
  late T _z;

  m() {
    _y = x;
  }

  n(Fields<T> c) {
    c._z = x;
  }
}

testField() {
  Fields<Object> c = new Fields<int>();
  Expect.throwsTypeError(() => c.x = 'hello');

  Fields<dynamic> d = new Fields<int>();
  Expect.throwsTypeError(() => c.x = 'hello');
}

testPrivateFields() {
  Fields<Object> c = new Fields<int>()..x = 42;
  c.m();
  Expect.equals(c._y, 42);

  Fields<Object> c2 = new Fields<String>()..x = 'hi';
  c2.n(c2);
  Expect.equals(c2._z, 'hi');
  Expect.throwsTypeError(() => c.n(c2));
  Expect.equals(c2._z, 'hi');
}

class NumBounds<T extends num> {
  bool m(T t) => t.isNegative;
}

class MethodTakesNum extends NumBounds<int> {
  bool m(num obj) => obj.isNegative; // does not need check
}

class MethodTakesInt extends NumBounds<int> {
  bool m(int obj) => obj.isNegative; // needs a check
}

testClassBounds() {
  NumBounds<num> d = new MethodTakesNum();
  Expect.equals(d.m(-1.1), true);
  d = new MethodTakesInt();
  Expect.throwsTypeError(() => d.m(-1.1));
}

typedef void F<T>(T t);
typedef G<T> = void Function<S extends T>(S s);

class FnChecks<T> {
  late F<T> f;
  late G<T> g;
  late T _t;
  T getT() => _t;
  F<T> setterForT() {
    return (T t) {
      _t = t;
    };
  }
}

testReturnOfFunctionType() {
  FnChecks<int> cInt = new FnChecks<int>();
  FnChecks<Object> cObj = cInt;
  Expect.throwsTypeError(() => cObj.setterForT());
  Expect.throwsTypeError(() => (cObj.setterForT() as F<Object>));
  FnChecks<dynamic> cDyn = cInt;
  Expect.throwsTypeError(() => cDyn.setterForT());
  Expect.throwsTypeError(
      () => (cDyn as dynamic).setterForT()('hi')); // dcall throws
  cInt.setterForT()(42);
  Expect.equals(cObj.getT(), 42);
}

testTearoffReturningFunctionType() {
  FnChecks<int> cInt = new FnChecks<int>();
  FnChecks<Object> cObj = cInt;

  Expect.throwsTypeError(
      () => cObj.setterForT, 'unsound tear-off throws at runtime');
  Expect.equals(cInt.setterForT, cInt.setterForT, 'sound tear-off works');
}

testFieldOfFunctionType() {
  FnChecks<Object> c = new FnChecks<String>()..f = (String b) {};
  Expect.throwsTypeError(() {
    F<Object> f = c.f;
  });
  Expect.throwsTypeError(() {
    Object f = c.f;
  });
  Expect.throwsTypeError(() => c.f);
  Expect.throwsTypeError(() => c.f(42));
  Expect.throwsTypeError(() => c.f('hi'));
  FnChecks<String> cStr = c as FnChecks<String>;
  cStr.f('hi');
  FnChecks<dynamic> cDyn = c;
  Expect.throwsTypeError(() => cDyn.f);
  Expect.throwsTypeError(() => (cDyn as dynamic).f(42)); // dcall throws
}

testFieldOfGenericFunctionType() {
  FnChecks<Object> c = new FnChecks<num>()
    ..g = <S extends num>(S s) => s.isNegative;

  Expect.throwsTypeError(() {
    G<Object> g = c.g;
  });
  Expect.throwsTypeError(() {
    var g = c.g;
  });
  Expect.throwsTypeError(() => c.g<String>('hi'));
  Expect.throwsTypeError(() => c.g<int>(42));
  FnChecks<num> cNum = c as FnChecks<num>;
  cNum.g(42);
}

class Base {
  int _t = 0;
  add(int t) {
    _t += t;
  }
}

abstract class I<T> {
  add(T t);
}

class ExtendsBase extends Base implements I<int> {}

class MixinBase extends Object with Base implements I<int> {}

class MixinBase2 = Object with Base implements I<int>;

testMixinApplication() {
  I<Object> i = new ExtendsBase();
  I<Object> j = new MixinBase();
  I<Object> k = new MixinBase2();
  Expect.throwsTypeError(() => i.add('hi'));
  Expect.throwsTypeError(() => j.add('hi'));
  Expect.throwsTypeError(() => k.add('hi'));
}

class GenericMethodBounds<T> {
  Type get t => T;
  GenericMethodBounds<E> foo<E extends T>() => new GenericMethodBounds<E>();
  GenericMethodBounds<E> bar<E extends void Function(T)>() =>
      new GenericMethodBounds<E>();
}

class GenericMethodBoundsDerived extends GenericMethodBounds<num> {
  GenericMethodBounds<E> foo<E extends num>() => new GenericMethodBounds<E>();
  GenericMethodBounds<E> bar<E extends void Function(num)>() =>
      new GenericMethodBounds<E>();
}

GenericMethodBounds<E> Function<E extends T>() genericFunctionWithBounds<T>() {
  inner<E extends T>() => new GenericMethodBounds<E>();
  return inner;
}

testGenericMethodBounds() {
  test(GenericMethodBounds<Object?> g) {
    Expect.throwsTypeError(() => g.foo<String>());
    Expect.throwsTypeError(() => g.foo());
    Expect.equals(g.foo<Never>().t, Never);
    Expect.equals(g.foo<int>().t, int);
    Expect.isFalse(g.foo<int>() is GenericMethodBounds<double>);
    g.bar<Function(Object?)>();
    dynamic d = g;
    d.bar<Function(num)>();
    Expect.throwsTypeError(() => d.bar<Function(String)>());
    Expect.throwsTypeError(() => d.bar<Function(Never)>());
  }

  test(new GenericMethodBounds<num>());
  test(new GenericMethodBounds<int>());
  test(new GenericMethodBoundsDerived());
  test(genericFunctionWithBounds<num>()<int>());
}

class ClassF<T> {
  late T x;
  void call(T t) {
    x = t;
  }
}

testCallMethod() {
  ClassF<int> cc = new ClassF<int>();
  ClassF<Object> ca = cc; // An upcast, per covariance.
  F<Object> f = ca;
  void f2(Object? x) {}
  Expect.equals(f.runtimeType, f2.runtimeType);
  Expect.throwsTypeError(() => f(new Object()));
}

class TearOff<T> {
  method1(T t) => null; // needs check
  method2(Function(T) takesT) => null;
  method3(T Function() returnsT) => null; // needs check
  method4(Function(Function(T)) takesTakesT) => null; // needs check
  method5(Function(T Function()) takesReturnsT) => null;
  method6(Function(T) Function() returnsTakesT) => null;
  method7(T Function() Function() returnsReturnsT) => null; // needs check
}

typedef F1 = dynamic Function(Object?);
typedef F2 = dynamic Function(dynamic Function(int));
typedef F3 = dynamic Function(dynamic Function(int Function()));
typedef F4 = dynamic Function(dynamic Function(int) Function());

testTearOffRuntimeType() {
  expectRTTI(tearoff, type) => Expect.equals(tearoff.runtimeType, type,
      'covariant params should reify with Object? as their type');

  TearOff<num> t = new TearOff<int>();
  expectRTTI(t.method1, F1);

  expectRTTI(t.method2, F2);
  expectRTTI(t.method3, F1);

  expectRTTI(t.method4, F1);
  expectRTTI(t.method5, F3);
  expectRTTI(t.method6, F4);
  expectRTTI(t.method7, F1);
}

main() {
  testField();
  testPrivateFields();
  testClassBounds();
  testReturnOfFunctionType();
  testTearoffReturningFunctionType();
  testFieldOfFunctionType();
  testFieldOfGenericFunctionType();
  testMixinApplication();
  testGenericMethodBounds();
  testCallMethod();
  testTearOffRuntimeType();
}
