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

library cancelable_future;

import 'dart:async';

/**
 * Type of callback called when the future returned by a CancelableCompleter
 * is canceled.
 */
typedef void CancelHandler();

/**
 * A way to produce [CancelableFuture] objects and to complete them later with
 * a value or error.
 *
 * This class behaves like the standard library [Completer] class, except that
 * its [future] getter returns a [CancelableFuture].
 *
 * If the future is canceled before being completed, the [CancelHandler] which
 * was passed to the constructor is invoked, and any further attempt to
 * complete the future has no effect.  For example, in the following code:
 *
 *     main() {
 *       var cc = new CancelableCompleter(() {
 *         print('cancelled'); // (2)
 *       });
 *       cc.future.then((value) {
 *         print('completed with value $value');
 *       }, onError: (error) {
 *         print('completed with error $error'); // (3)
 *       });
 *       cc.future.cancel(); // (1)
 *     }
 *
 * The call at (1) causes (2) to be invoked immediately.  (3) will be invoked
 * later (on a microtask), with an error that is an instance of
 * [FutureCanceledError].
 *
 * Note that since the closure passed to then() is executed on a microtask,
 * there is a short window of time between the call to [complete] and the
 * client being informed that the future has completed.  During this window,
 * any attempt to cancel the future will have no effect.  For example, in the
 * following code:
 *
 *     main() {
 *       var cc = new CancelableCompleter(() {
 *         print('cancelled'); // (3)
 *       });
 *       cc.future.then((value) {
 *         print('completed with value $value'); // (4)
 *       }, onError: (error) {
 *         print('completed with error $error');
 *       });
 *       cc.complete(100); // (1)
 *       cc.future.cancel(); // (2)
 *     }
 *
 * The call at (1) will place the completer in the "completed" state, so the
 * call at (2) will have no effect (in particular, (3) won't ever execute).
 * Later, (4) will be invoked on a microtask.
 */
class CancelableCompleter<T> implements Completer<T> {
  /**
   * The completer which holds the state of the computation.  If the
   * computation is canceled, this completer will remain in the non-completed
   * state.
   */
  final Completer<T> _innerCompleter = new Completer<T>.sync();

  /**
   * The completer which holds the future that is exposed to the client
   * through [future].  If the computation is canceled, this completer will
   * be completed with a FutureCanceledError.
   */
  final Completer<T> _outerCompleter = new Completer<T>();

  /**
   * The callback to invoke if the 'cancel' method is called on the future
   * returned by [future].  This callback will only be invoked if the future
   * is canceled before being completed.
   */
  final CancelHandler _onCancel;

  _CancelableCompleterFuture<T> _future;

  /**
   * Create a CancelableCompleter that will invoke the given callback
   * synchronously if its future is canceled.  The callback will not be
   * invoked if the future is completed before being canceled.
   */
  CancelableCompleter(this._onCancel) {
    _future = new _CancelableCompleterFuture<T>(this);

    // When the client completes the inner completer, we need to check whether
    // the outer completer has been completed.  If it has, then the operation
    // was canceled before it finished, and it's too late to un-cancel it, so
    // we just ignore the result from the inner completer.  If it hasn't, then
    // we simply pass along the result from the inner completer to the outer
    // completer.
    //
    // Note that the reason it is safe for the inner completer to be
    // synchronous is that we don't expose its future to client code, and we
    // only use it to complete the outer completer (which is asynchronous).
    _innerCompleter.future.then((T value) {
      if (!_outerCompleter.isCompleted) {
        _outerCompleter.complete(value);
      }
    }, onError: (Object error, StackTrace stackTrace) {
      if (!_outerCompleter.isCompleted) {
        _outerCompleter.completeError(error, stackTrace);
      }
    });
  }

  /**
   * The [CancelableFuture] that will contain the result provided to this
   * completer.
   */
  @override
  CancelableFuture<T> get future => _future;

  /**
   * Whether the future has been completed.  This is independent of whether
   * the future has been canceled.
   */
  @override
  bool get isCompleted => _innerCompleter.isCompleted;

  /**
   * Complete [future] with the supplied value.  If the future has previously
   * been canceled, this will have no effect on [future], however it will
   * still set [isCompleted] to true.
   */
  @override
  void complete([value]) {
    _innerCompleter.complete(value);
  }

  /**
   * Complete [future] with an error.  If the future has previously been
   * canceled, this will have no effect on [future], however it will still set
   * [isCompleted] to true.
   */
  @override
  void completeError(Object error, [StackTrace stackTrace]) {
    _innerCompleter.completeError(error, stackTrace);
  }

  void _cancel() {
    if (!_outerCompleter.isCompleted) {
      _outerCompleter.completeError(new FutureCanceledError());
      _onCancel();
    }
  }
}

/**
 * An object representing a delayed computation that can be canceled.
 */
abstract class CancelableFuture<T> implements Future<T> {
  /**
   * A CancelableFuture containing the result of calling [computation]
   * asynchronously.  Since the computation is started without delay, calling
   * the future's cancel method will have no effect.
   */
  factory CancelableFuture(computation()) =>
      new _WrappedFuture<T>(new Future<T>(computation));

  /**
   * A CancelableFuture containing the result of calling [computation] after
   * [duration] has passed.
   *
   * TODO(paulberry): if the future is canceled before the duration has
   * elapsed, the computation should not be performed.
   */
  factory CancelableFuture.delayed(Duration duration, [computation()]) =>
      new _WrappedFuture<T>(new Future<T>.delayed(duration, computation));

  /**
   * A CancelableFuture that completes with error.  Since the future is
   * completed without delay, calling the future's cancel method will have no
   * effect.
   */
  factory CancelableFuture.error(Object error, [StackTrace stackTrace]) =>
      new _WrappedFuture<T>(new Future<T>.error(error, stackTrace));

  /**
   * A CancelableFuture containing the result of calling [computation]
   * asynchronously with scheduleMicrotask.  Since the computation is started
   * without delay, calling the future's cancel method will have no effect.
   */
  factory CancelableFuture.microtask(computation()) =>
      new _WrappedFuture<T>(new Future<T>.microtask(computation));

  /**
   * A CancelableFuture containing the result of immediately calling
   * [computation].  Since the computation is started without delay, calling
   * the future's cancel method will have no effect.
   */
  factory CancelableFuture.sync(computation()) =>
      new _WrappedFuture<T>(new Future<T>.sync(computation));

  /**
   * A CancelableFuture whose value is available in the next event-loop
   * iteration.  Since the value is available without delay, calling the
   * future's cancel method will have no effect.
   */
  factory CancelableFuture.value([value]) =>
      new _WrappedFuture<T>(new Future<T>.value(value));

  /**
   * If the delayed computation has not yet completed, attempt to cancel it.
   * Note that the cancellation is not always possible.  If the computation
   * could be canceled, the future is completed with a FutureCanceledError.
   * Otherwise it will behave as though cancel() was not called.
   *
   * Note that attempting to cancel a future that has already completed will
   * never succeed--futures that have already completed retain their final
   * state forever.
   */
  void cancel();
}

/**
 * Error which is used to complete any [CancelableFuture] which has been
 * successfully canceled by calling its 'cancel' method.
 */
class FutureCanceledError {}

class _CancelableCompleterFuture<T> implements CancelableFuture<T> {
  final CancelableCompleter<T> _completer;

  _CancelableCompleterFuture(this._completer);

  @override
  Stream<T> asStream() {
    // TODO(paulberry): Implement this in such a way that
    // StreamSubscription.cancel() cancels the future.
    return _completer._outerCompleter.future.asStream();
  }

  @override
  void cancel() {
    _completer._cancel();
  }

  @override
  Future catchError(Function onError, {bool test(Object error)}) =>
      _completer._outerCompleter.future.catchError(onError, test: test);

  @override
  Future then(onValue(T value), {Function onError}) =>
      _completer._outerCompleter.future.then(onValue, onError: onError);

  @override
  Future timeout(Duration timeLimit, {onTimeout()}) {
    // TODO(paulberry): Implement this in such a way that a timeout cancels
    // the future.
    return _completer._outerCompleter.future
        .timeout(timeLimit, onTimeout: onTimeout);
  }

  @override
  Future<T> whenComplete(action()) =>
      _completer._outerCompleter.future.whenComplete(action);
}

/**
 * A CancelableFuture that wraps an ordinary Future.  Attempting to cancel a
 * _WrappedFuture has no effect.
 */
class _WrappedFuture<T> implements CancelableFuture<T> {
  final Future<T> _future;

  _WrappedFuture(this._future);

  @override
  Stream<T> asStream() => _future.asStream();

  @override
  void cancel() {}

  @override
  Future catchError(Function onError, {bool test(Object error)}) =>
      _future.catchError(onError, test: test);

  @override
  Future then(onValue(value), {Function onError}) =>
      _future.then(onValue, onError: onError);

  @override
  Future timeout(Duration timeLimit, {onTimeout()}) =>
      _future.timeout(timeLimit, onTimeout: onTimeout);

  @override
  Future<T> whenComplete(action()) => _future.whenComplete(action);
}
