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

// Check that the `flatten` function is implemented and applied correctly
// when applied to interfaces that have `Future` as a superinterface.

import 'dart:async';

import 'package:expect/async_helper.dart';
import 'package:expect/expect.dart';

import 'package:expect/static_type_helper.dart';

mixin Base {
  noSuchMethod(Invocation invocation) {
    if (const {
      #then,
      #catchError,
      #whenComplete,
    }.contains(invocation.memberName)) {
      // Throw a sentinel value (using the receiver since it's available)
      // when one of the `Future` callback methods is called.
      throw this;
    }
    return super.noSuchMethod(invocation);
  }
}

extension on Future<void> {
  Future<void> ignoreError<T>() => then(
    (_) => null,
    onError: (e) {
      if (e is! T) throw e;
    },
  );
}

class Derived<T> = Object with Base implements Future<T>;

class FixedPoint<T> = Object with Base implements Future<FixedPoint<T>>;

class Divergent<T> = Object
    with Base
    implements Future<Divergent<Divergent<T>>>;

void main() async {
  asyncStart();
  // ----- Test the static types of await on the non-standard futures.

  bool obscureFalse = DateTime.now().millisecondsSinceEpoch < 0;

  if (obscureFalse) {
    var x1 = await Derived<int>();
    x1.expectStaticType<Exactly<int>>();

    var x2 = await FixedPoint<int>();
    x2.expectStaticType<Exactly<FixedPoint<int>>>();

    var x3 = await Divergent<int>();
    x3.expectStaticType<Exactly<Divergent<Divergent<int>>>>();
  }

  // ----- flatten(Derived<int>) == int.

  try {
    int x = await Derived<int>();
    Expect.fail("Derived did not throw");
  } on Derived {
    // Expected throw.
  }

  Future<int> f1() async => Derived<int>();

  // A non-standard future which implements `Future<int>` can be returned
  // in an async function with return type `Future<int>`. It does not
  // implement any members, so we need to ignore the dynamic error that
  // occurs when any of its future callback methods is called.
  f1().ignoreError<Derived>();

  Future<int> f2() async {
    return Derived<int>();
  }

  // Like the `f1` case, using a `{}` function.
  f2().ignoreError<Derived>();

  Future<int> x1 = (() async => Derived<int>())();

  try {
    await x1;
    Expect.fail("Derived did not throw");
  } on Derived {
    // Expected throw.
  }

  // ----- flatten(FixedPoint<int>) == FixedPoint<int>.

  try {
    FixedPoint<int> x = await FixedPoint<int>();
    Expect.fail("FixedPoint did not throw");
  } on FixedPoint {
    // Expected throw.
  }

  Future<FixedPoint<int>> f3() async => FixedPoint<int>();

  f3().ignoreError<FixedPoint>();

  Future<FixedPoint<int>> f4() async {
    return FixedPoint<int>();
  }

  f4().ignoreError<FixedPoint>();

  Future<FixedPoint<int>> x2 = (() async => FixedPoint<int>())();

  try {
    await x2;
    Expect.fail("FixedPoint did not throw");
  } on FixedPoint {
    // Expected throw.
  }

  // ----- flatten(Divergent<int>) == Divergent<Divergent<int>>.

  try {
    Divergent<Divergent<int>> x = await Divergent<int>();
    Expect.fail("Divergent did not throw");
  } on Divergent {
    // Expected throw.
  }

  Future<Divergent<Divergent<int>>> f5() async => Divergent<int>();
  f5().ignoreError<Divergent>();

  Future<Divergent<Divergent<int>>> f6() async {
    return Divergent<int>();
  }

  f6().ignoreError<Divergent>();

  Future<Divergent<Divergent<int>>> f7() async => Divergent<int>();
  Future<Divergent<Divergent<int>>> x3 = f7();

  try {
    await x3;
    Expect.fail("Divergent did not throw");
  } on Divergent {
    // Expected throw.
  }
  asyncEnd();
}
