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

typedef Future<Null> Task();

class ForeignFuture implements Future<Null> {
  ForeignFuture(List<Task> tasks) {
    tasks.forEach(_addTask);
  }

  Future<Null> _future;

  void _addTask(Task task) {
    _future = (_future == null) ? task() : _future.then((_) => task());
  }

  Future<S> then<S>(FutureOr<S> onValue(Null _), {Function onError}) {
    assert(_future != null);
    return _future.then((_) {
      _future = null;
      return onValue(null);
    }, onError: (error, trace) {
      _future = null;
      if (onError != null) {
        onError(error, trace);
      }
    });
  }

  Stream<Null> asStream() {
    return new Stream.fromFuture(this);
  }

  Future<Null> catchError(onError, {bool test(Object error)}) {
    print('Unimplemented catchError');
    return null;
  }

  Future<Null> timeout(Duration timeLimit, {onTimeout()}) {
    print('Unimplemented timeout');
    return null;
  }

  Future<Null> whenComplete(action()) {
    print('Unimplemented whenComplete');
    return null;
  }
}

var r1;

Future<Null> hello() async {
  r1 = 'hello';
  throw new Exception('error');
}

Future<String> world() async {
  try {
    await new ForeignFuture([hello]);
  } catch (e) {}
  return 'world';
}

void main() {
  asyncStart();
  () async {
    var r2 = await world();
    Expect.equals('hello', r1);
    Expect.equals('world', r2);
    asyncEnd();
  }();
}
