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

void testInstantiateToBounds() {
  f<T extends num, U extends T>() => [T, U];
  g<T extends List<U>, U extends int>() => [T, U];
  h<T extends num, U extends T>(T x, U y) => h.runtimeType.toString();

  Expect.listEquals([num, num], (f as dynamic)());
  Expect.equals('List<int>|int', (g as dynamic)().join('|'));
  Expect.equals('<T extends num, U extends T>(T, U) => String',
      (h as dynamic)(null, null));

  i<T extends Iterable<T>>() => null;
  j<T extends Iterable<S>, S extends T>() => null;
  Expect.throws(
      () => (i as dynamic)(), (e) => '$e'.contains('Instantiate to bounds'));
  Expect.throws(
      () => (j as dynamic)(), (e) => '$e'.contains('Instantiate to bounds'));
}

void testChecksBound() {
  f<T extends num>(T x) => x;
  Expect.equals((f as dynamic)(42), 42);
  Expect.throws(() => (f as dynamic)('42'));

  msg(t1, t2, tf) => Expect.throws(() => (f as dynamic)<Object>(42),
      (e) => '$e' == 'type `Object` does not extend `num` of `T');

  g<T extends U, U extends num>(T x, U y) => x;
  Expect.equals((g as dynamic)(42.0, 100), 42.0);
  Expect.throws(() => (g as dynamic)('hi', 100));
  Expect.throws(() => (g as dynamic)<double, int>(42.0, 100),
      (e) => '$e' == 'type `double` does not extend `int` of `T`.');

  Expect.throws(() => (g as dynamic)<num, Object>(42.0, 100),
      (e) => '$e' == 'type `Object` does not extend `num` of `U`.');
}

typedef G<U> = T Function<T extends U>(T x);

void testSubtype() {
  f<T extends num>(T x) => x + 2;

  dynamic d = f;
  Expect.equals(d(40.0), 42.0);
  Expect.equals((f as G<int>)(40), 42);
  Expect.equals((d as G<int>)(40), 42);
  Expect.equals((f as G<double>)(40.0), 42.0);
  Expect.equals((d as G<double>)(40.0), 42.0);

  d as G<Null>;
  Expect.throws(() => d as G);
  Expect.throws(() => d as G<Object>);
  Expect.throws(() => d as G<String>);
}

void testToString() {
  // TODO(jmesserly): I don't think the cast on `y` should be required.
  num f<T extends num, U extends T>(T x, U y) => min(x, y as num);
  num g<T, U>(T x, U y) => max(x as num, y as num);
  String h<T, U>(T x, U y) => h.runtimeType.toString();
  Expect.equals(
      f.runtimeType.toString(), '<T extends num, U extends T>(T, U) => num');
  Expect.equals(g.runtimeType.toString(), '<T, U>(T, U) => num');
  Expect.equals(h(42, 123.0), '<T, U>(T, U) => String');
}

main() {
  testInstantiateToBounds();
  testToString();
  testChecksBound();
  testSubtype();
}
