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

part of dart.async;

/// Abstract and private interface for a place to put events.
abstract class _EventSink<T> {
  void _add(T data);
  void _addError(Object error, StackTrace stackTrace);
  void _close();
}

/// Abstract and private interface for a place to send events.
///
/// Used by event buffering to finally dispatch the pending event, where
/// [_EventSink] is where the event first enters the stream subscription,
/// and may yet be buffered.
abstract class _EventDispatch<T> {
  void _sendData(T data);
  void _sendError(Object error, StackTrace stackTrace);
  void _sendDone();
}

/// Default implementation of stream subscription of buffering events.
///
/// The only public methods are those of [StreamSubscription], so instances of
/// [_BufferingStreamSubscription] can be returned directly as a
/// [StreamSubscription] without exposing internal functionality.
///
/// The [StreamController] is a public facing version of [Stream] and this class,
/// with some methods made public.
///
/// The user interface of [_BufferingStreamSubscription] are the following
/// methods:
///
/// * [_add]: Add a data event to the stream.
/// * [_addError]: Add an error event to the stream.
/// * [_close]: Request to close the stream.
/// * [_onCancel]: Called when the subscription will provide no more events,
///     either due to being actively canceled, or after sending a done event.
/// * [_onPause]: Called when the subscription wants the event source to pause.
/// * [_onResume]: Called when allowing new events after a pause.
///
/// The user should not add new events when the subscription requests a paused,
/// but if it happens anyway, the subscription will enqueue the events just as
/// when new events arrive while still firing an old event.
class _BufferingStreamSubscription<T>
    implements StreamSubscription<T>, _EventSink<T>, _EventDispatch<T> {
  /// The `cancelOnError` flag from the `listen` call.
  static const int _STATE_CANCEL_ON_ERROR = 1 << 0;

  /// Whether the "done" event has been received.
  /// No further events are accepted after this.
  static const int _STATE_CLOSED = 1 << 1;

  /// Set if the input has been asked not to send events.
  ///
  /// This is not the same as being paused, since the input will remain paused
  /// after a call to [resume] if there are pending events.
  static const int _STATE_INPUT_PAUSED = 1 << 2;

  /// Whether the subscription has been canceled.
  ///
  /// Set by calling [cancel], or by handling a "done" event, or an "error" event
  /// when `cancelOnError` is true.
  static const int _STATE_CANCELED = 1 << 3;

  /// Set when either:
  ///
  ///   * an error is sent, and [cancelOnError] is true, or
  ///   * a done event is sent.
  ///
  /// If the subscription is canceled while _STATE_WAIT_FOR_CANCEL is set, the
  /// state is unset, and no further events must be delivered.
  static const int _STATE_WAIT_FOR_CANCEL = 1 << 4;

  /// Set when [_onError] is set to something other than [_nullErrorHandler].
  /// Is used by VM to decide whether subscription is going to handle an
  /// error or not.
  ///
  /// When changing this value make sure to update runtime/vm/stack_trace.cc
  static const int _STATE_HAS_ERROR_HANDLER = 1 << 5;

  /// Caveat: [_canFire] expects these bits to be at the top so that it
  /// can use a single `< _STATE_IN_CALLBACK` comparison to test for all
  /// of them.
  static const int _STATE_IN_CALLBACK = 1 << 6;
  static const int _STATE_HAS_PENDING = 1 << 7;
  static const int _STATE_PAUSE_COUNT = 1 << 8;

  /* Event handlers provided in constructor. */
  @pragma("vm:entry-point")
  void Function(T) _onData;

  @pragma("vm:entry-point")
  Function _onError;

  @pragma("vm:entry-point")
  void Function() _onDone;

  final Zone _zone;

  /// Bit vector based on state-constants above.
  ///
  /// Upper bits (starting at _STATE_PAUSE_COUNT) contain number of times
  /// this subscription was paused.
  @pragma("vm:entry-point")
  int _state;

  // TODO(floitsch): reuse another field
  /// The future [_onCancel] may return.
  Future? _cancelFuture;

  /// Queue of pending events.
  ///
  /// Is created when necessary, or set in constructor for preconfigured events.
  _PendingEvents<T>? _pending;

  _BufferingStreamSubscription(
    void onData(T data)?,
    Function? onError,
    void onDone()?,
    bool cancelOnError,
  ) : this.zoned(Zone.current, onData, onError, onDone, cancelOnError);

  _BufferingStreamSubscription.zoned(
    this._zone,
    void onData(T data)?,
    Function? onError,
    void onDone()?,
    bool cancelOnError,
  ) : _state =
          (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) |
          (onError != null ? _STATE_HAS_ERROR_HANDLER : 0),
      _onData = _registerDataHandler<T>(_zone, onData),
      _onError = _registerErrorHandler(_zone, onError),
      _onDone = _registerDoneHandler(_zone, onDone);

  /// Sets the subscription's pending events object.
  ///
  /// This can only be done once. The pending events object is used for the
  /// rest of the subscription's life cycle.
  void _setPendingEvents(_PendingEvents<T>? pendingEvents) {
    assert(_pending == null);
    if (pendingEvents == null) return;
    _pending = pendingEvents;
    if (!pendingEvents.isEmpty) {
      _state |= _STATE_HAS_PENDING;
      pendingEvents.schedule(this);
    }
  }

  // StreamSubscription interface.

  void onData(void handleData(T event)?) {
    _onData = _registerDataHandler<T>(_zone, handleData);
  }

  static void Function(T) _registerDataHandler<T>(
    Zone zone,
    void Function(T)? handleData,
  ) {
    return zone.registerUnaryCallback<void, T>(handleData ?? _nullDataHandler);
  }

  void onError(Function? handleError) {
    if (handleError == null) {
      _state &= ~_STATE_HAS_ERROR_HANDLER;
    } else {
      _state |= _STATE_HAS_ERROR_HANDLER;
    }
    _onError = _registerErrorHandler(_zone, handleError);
  }

  static Function _registerErrorHandler(Zone zone, Function? handleError) {
    // TODO(lrn): Consider whether we need to register the null handler.
    handleError ??= _nullErrorHandler;
    if (handleError is void Function(Object, StackTrace)) {
      return zone.registerBinaryCallback<dynamic, Object, StackTrace>(
        handleError,
      );
    }
    if (handleError is void Function(Object)) {
      return zone.registerUnaryCallback<dynamic, Object>(handleError);
    }
    throw new ArgumentError(
      "handleError callback must take either an Object "
      "(the error), or both an Object (the error) and a StackTrace.",
    );
  }

  void onDone(void handleDone()?) {
    _onDone = _registerDoneHandler(_zone, handleDone);
  }

  static void Function() _registerDoneHandler(
    Zone zone,
    void Function()? handleDone,
  ) {
    return zone.registerCallback(handleDone ?? _nullDoneHandler);
  }

  void pause([Future<void>? resumeSignal]) {
    if (_isCanceled) return;
    bool wasPaused = _isPaused;
    bool wasInputPaused = _isInputPaused;
    // Increment pause count and mark input paused (if it isn't already).
    _state = (_state + _STATE_PAUSE_COUNT) | _STATE_INPUT_PAUSED;
    resumeSignal?.whenComplete(resume);
    if (!wasPaused) _pending?.cancelSchedule();
    if (!wasInputPaused && !_inCallback) _guardCallback(_onPause);
  }

  void resume() {
    if (_isCanceled) return;
    if (_isPaused) {
      _decrementPauseCount();
      if (!_isPaused) {
        if (_hasPending && !_pending!.isEmpty) {
          // Input is still paused.
          _pending!.schedule(this);
        } else {
          assert(_mayResumeInput);
          _state &= ~_STATE_INPUT_PAUSED;
          if (!_inCallback) _guardCallback(_onResume);
        }
      }
    }
  }

  Future cancel() {
    // The user doesn't want to receive any further events. If there is an
    // error or done event pending (waiting for the cancel to be done) discard
    // that event.
    _state &= ~_STATE_WAIT_FOR_CANCEL;
    if (!_isCanceled) {
      _cancel();
    }
    return _cancelFuture ?? Future._nullFuture;
  }

  Future<E> asFuture<E>([E? futureValue]) {
    E resultValue;
    if (futureValue == null) {
      if (!typeAcceptsNull<E>()) {
        throw ArgumentError.notNull("futureValue");
      }
      resultValue = futureValue as dynamic;
    } else {
      resultValue = futureValue;
    }
    // Overwrite the onDone and onError handlers.
    _Future<E> result = new _Future<E>();
    _onDone = () {
      result._complete(resultValue);
    };
    _state |= _STATE_HAS_ERROR_HANDLER;
    _onError = (Object error, StackTrace stackTrace) {
      Future cancelFuture = cancel();
      if (!identical(cancelFuture, Future._nullFuture)) {
        cancelFuture.whenComplete(() {
          result._completeError(error, stackTrace);
        });
      } else {
        result._completeError(error, stackTrace);
      }
    };
    return result;
  }

  // State management.

  bool get _isInputPaused => (_state & _STATE_INPUT_PAUSED) != 0;
  bool get _isClosed => (_state & _STATE_CLOSED) != 0;
  bool get _isCanceled => (_state & _STATE_CANCELED) != 0;
  bool get _waitsForCancel => (_state & _STATE_WAIT_FOR_CANCEL) != 0;
  bool get _inCallback => (_state & _STATE_IN_CALLBACK) != 0;
  bool get _hasPending => (_state & _STATE_HAS_PENDING) != 0;
  bool get _isPaused => _state >= _STATE_PAUSE_COUNT;
  bool get _canFire => _state < _STATE_IN_CALLBACK;
  bool get _mayResumeInput => !_isPaused && (_pending?.isEmpty ?? true);
  bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0;

  bool get isPaused => _isPaused;

  void _cancel() {
    _state |= _STATE_CANCELED;
    if (_hasPending) {
      _pending!.cancelSchedule();
    }
    if (!_inCallback) _pending = null;
    _cancelFuture = _onCancel();
  }

  /// Decrements the pause count.
  ///
  /// Does not automatically unpause the input (call [_onResume]) when
  /// the pause count reaches zero. This is handled elsewhere, and only
  /// if there are no pending events buffered.
  void _decrementPauseCount() {
    assert(_isPaused);
    _state -= _STATE_PAUSE_COUNT;
  }

  // _EventSink interface.

  void _add(T data) {
    assert(!_isClosed);
    if (_isCanceled) return;
    if (_canFire) {
      _sendData(data);
    } else {
      _addPending(new _DelayedData<T>(data));
    }
  }

  void _addError(Object error, StackTrace stackTrace) {
    _trySetStackTrace(error, stackTrace);
    if (_isCanceled) return;
    if (_canFire) {
      _sendError(error, stackTrace); // Reports cancel after sending.
    } else {
      _addPending(new _DelayedError(error, stackTrace));
    }
  }

  void _close() {
    assert(!_isClosed);
    if (_isCanceled) return;
    _state |= _STATE_CLOSED;
    if (_canFire) {
      _sendDone();
    } else {
      _addPending(const _DelayedDone());
    }
  }

  // Hooks called when the input is paused, unpaused or canceled.
  // These must not throw. If overwritten to call user code, include suitable
  // try/catch wrapping and send any errors to
  // [_Zone.current.handleUncaughtError].
  void _onPause() {
    assert(_isInputPaused);
  }

  void _onResume() {
    assert(!_isInputPaused);
  }

  Future<void>? _onCancel() {
    assert(_isCanceled);
    return null;
  }

  // Handle pending events.

  /// Add a pending event.
  ///
  /// If the subscription is not paused, this also schedules a firing
  /// of pending events later (if necessary).
  void _addPending(_DelayedEvent event) {
    var pending = _pending ??= _PendingEvents<T>();
    pending.add(event);
    if (!_hasPending) {
      _state |= _STATE_HAS_PENDING;
      if (!_isPaused) {
        pending.schedule(this);
      }
    }
  }

  /* _EventDispatch interface. */

  void _sendData(T data) {
    assert(!_isCanceled);
    assert(!_isPaused);
    assert(!_inCallback);
    bool wasInputPaused = _isInputPaused;
    _state |= _STATE_IN_CALLBACK;
    _zone.runUnaryGuarded(_onData, data);
    _state &= ~_STATE_IN_CALLBACK;
    _checkState(wasInputPaused);
  }

  void _sendError(Object error, StackTrace stackTrace) {
    assert(!_isCanceled);
    assert(!_isPaused);
    assert(!_inCallback);
    bool wasInputPaused = _isInputPaused;

    void sendError() {
      // If the subscription has been canceled while waiting for the cancel
      // future to finish we must not report the error.
      if (_isCanceled && !_waitsForCancel) return;
      _state |= _STATE_IN_CALLBACK;
      // TODO(floitsch): this dynamic should be 'void'.
      var onError = _onError;
      if (onError is void Function(Object, StackTrace)) {
        _zone.runBinaryGuarded<Object, StackTrace>(onError, error, stackTrace);
      } else {
        _zone.runUnaryGuarded<Object>(_onError as dynamic, error);
      }
      _state &= ~_STATE_IN_CALLBACK;
    }

    if (_cancelOnError) {
      _state |= _STATE_WAIT_FOR_CANCEL;
      _cancel();
      var cancelFuture = _cancelFuture;
      if (cancelFuture != null &&
          !identical(cancelFuture, Future._nullFuture)) {
        cancelFuture.whenComplete(sendError);
      } else {
        sendError();
      }
    } else {
      sendError();
      // Only check state if not cancelOnError.
      _checkState(wasInputPaused);
    }
  }

  void _sendDone() {
    assert(!_isCanceled);
    assert(!_isPaused);
    assert(!_inCallback);

    void sendDone() {
      // If the subscription has been canceled while waiting for the cancel
      // future to finish we must not report the done event.
      if (!_waitsForCancel) return;
      _state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK);
      _zone.runGuarded(_onDone);
      _state &= ~_STATE_IN_CALLBACK;
    }

    _cancel();
    _state |= _STATE_WAIT_FOR_CANCEL;
    var cancelFuture = _cancelFuture;
    if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) {
      cancelFuture.whenComplete(sendDone);
    } else {
      sendDone();
    }
  }

  /// Call a hook function.
  ///
  /// The call is properly wrapped in code to avoid other callbacks
  /// during the call, and it checks for state changes after the call
  /// that should cause further callbacks.
  void _guardCallback(void Function() callback) {
    assert(!_inCallback);
    bool wasInputPaused = _isInputPaused;
    _state |= _STATE_IN_CALLBACK;
    callback();
    _state &= ~_STATE_IN_CALLBACK;
    _checkState(wasInputPaused);
  }

  /// Check if the input needs to be informed of state changes.
  ///
  /// State changes are pausing, resuming and canceling.
  ///
  /// After canceling, no further callbacks will happen.
  ///
  /// The cancel callback is called after a user cancel, or after
  /// the final done event is sent.
  void _checkState(bool wasInputPaused) {
    assert(!_inCallback);
    if (_hasPending && _pending!.isEmpty) {
      _state &= ~_STATE_HAS_PENDING;
      if (_isInputPaused && _mayResumeInput) {
        _state &= ~_STATE_INPUT_PAUSED;
      }
    }
    // If the state changes during a callback, we immediately
    // make a new state-change callback. Loop until the state didn't change.
    while (true) {
      if (_isCanceled) {
        _pending = null;
        return;
      }
      bool isInputPaused = _isInputPaused;
      if (wasInputPaused == isInputPaused) break;
      _state ^= _STATE_IN_CALLBACK;
      if (isInputPaused) {
        _onPause();
      } else {
        _onResume();
      }
      _state &= ~_STATE_IN_CALLBACK;
      wasInputPaused = isInputPaused;
    }
    if (_hasPending && !_isPaused) {
      _pending!.schedule(this);
    }
  }
}

// -------------------------------------------------------------------
// Common base class for single and multi-subscription streams.
// -------------------------------------------------------------------
abstract class _StreamImpl<T> extends Stream<T> {
  // ------------------------------------------------------------------
  // Stream interface.

  StreamSubscription<T> listen(
    void onData(T data)?, {
    Function? onError,
    void onDone()?,
    bool? cancelOnError,
  }) {
    cancelOnError ??= false;
    StreamSubscription<T> subscription = _createSubscription(
      onData,
      onError,
      onDone,
      cancelOnError,
    );
    _onListen(subscription);
    return subscription;
  }

  // -------------------------------------------------------------------
  /// Create a subscription object. Called by [subscribe].
  StreamSubscription<T> _createSubscription(
    void onData(T data)?,
    Function? onError,
    void onDone()?,
    bool cancelOnError,
  ) {
    return new _BufferingStreamSubscription<T>(
      onData,
      onError,
      onDone,
      cancelOnError,
    );
  }

  /// Hook called when the subscription has been created.
  void _onListen(StreamSubscription subscription) {}
}

// Internal helpers.

/// Default data handler, does nothing.
void _nullDataHandler(dynamic value) {}

/// Default error handler, reports the error to the current zone's handler.
void _nullErrorHandler(Object error, StackTrace stackTrace) {
  Zone.current.handleUncaughtError(error, stackTrace);
}

/// Default done handler, does nothing.
void _nullDoneHandler() {}

/// A delayed event on a buffering stream subscription.
abstract class _DelayedEvent<T> {
  /// Added as a linked list on the [StreamController].
  _DelayedEvent? next;

  /// Execute the delayed event on the [StreamController].
  void perform(_EventDispatch<T> dispatch);
}

/// A delayed data event.
class _DelayedData<T> extends _DelayedEvent<T> {
  final T value;
  _DelayedData(this.value);
  void perform(_EventDispatch<T> dispatch) {
    dispatch._sendData(value);
  }
}

/// A delayed error event.
class _DelayedError extends _DelayedEvent {
  final Object error;
  final StackTrace stackTrace;

  _DelayedError(this.error, this.stackTrace);
  void perform(_EventDispatch dispatch) {
    dispatch._sendError(error, stackTrace);
  }
}

/// A delayed done event.
class _DelayedDone implements _DelayedEvent {
  const _DelayedDone();
  void perform(_EventDispatch dispatch) {
    dispatch._sendDone();
  }

  _DelayedEvent? get next => null;

  void set next(_DelayedEvent? _) {
    throw new StateError("No events after a done.");
  }
}

/// Container and manager of pending events for a stream subscription.
class _PendingEvents<T> {
  // No async event has been scheduled.
  static const int stateUnscheduled = 0;
  // An async event has been scheduled to run a function.
  static const int stateScheduled = 1;
  // An async event has been scheduled, but it will do nothing when it runs.
  // Async events can't be preempted.
  static const int stateCanceled = 3;

  /// State of being scheduled.
  ///
  /// Set to [stateScheduled] when pending events are scheduled for
  /// async dispatch. Since we can't cancel a [scheduleMicrotask] call, if
  /// scheduling is "canceled", the _state is simply set to [stateCanceled]
  /// which will make the async code do nothing except resetting [_state].
  ///
  /// If events are scheduled while the state is [stateCanceled], it is
  /// merely switched back to [stateScheduled], but no new call to
  /// [scheduleMicrotask] is performed.
  int _state = stateUnscheduled;

  /// First element in the list of pending events, if any.
  _DelayedEvent? firstPendingEvent;

  /// Last element in the list of pending events. New events are added after it.
  _DelayedEvent? lastPendingEvent;

  bool get isScheduled => _state == stateScheduled;
  bool get _eventScheduled => _state >= stateScheduled;

  /// Schedule an event to run later.
  ///
  /// If called more than once, it should be called with the same dispatch as
  /// argument each time. It may reuse an earlier argument in some cases.
  void schedule(_EventDispatch<T> dispatch) {
    if (isScheduled) return;
    assert(!isEmpty);
    if (_eventScheduled) {
      assert(_state == stateCanceled);
      _state = stateScheduled;
      return;
    }
    scheduleMicrotask(() {
      int oldState = _state;
      _state = stateUnscheduled;
      if (oldState == stateCanceled) return;
      handleNext(dispatch);
    });
    _state = stateScheduled;
  }

  void cancelSchedule() {
    if (isScheduled) _state = stateCanceled;
  }

  bool get isEmpty => lastPendingEvent == null;

  void add(_DelayedEvent event) {
    var lastEvent = lastPendingEvent;
    if (lastEvent == null) {
      firstPendingEvent = lastPendingEvent = event;
    } else {
      lastPendingEvent = lastEvent.next = event;
    }
  }

  void handleNext(_EventDispatch<T> dispatch) {
    assert(!isScheduled);
    assert(!isEmpty);
    _DelayedEvent event = firstPendingEvent!;
    _DelayedEvent? nextEvent = event.next;
    firstPendingEvent = nextEvent;
    if (nextEvent == null) {
      lastPendingEvent = null;
    }
    event.perform(dispatch);
  }

  void clear() {
    if (isScheduled) cancelSchedule();
    firstPendingEvent = lastPendingEvent = null;
  }
}

typedef void _BroadcastCallback<T>(StreamSubscription<T> subscription);

/// Done subscription that will send one done event as soon as possible.
class _DoneStreamSubscription<T> implements StreamSubscription<T> {
  // States of the subscription.
  //
  // The subscription will try to send a done event.
  // When created, it schedules a microtask to emit the
  // event to the current [_onDone] callback.
  // If paused when the microtask happens, the subscription won't
  // send the done event. It will reschedule a new microtask when
  // the subscription is resumed.
  // If cancelled, the event will not be sent, and a new
  // microtask won't be scheduled, and further pauses
  // are ignored.

  /// Sending a done event is allowed.
  ///
  /// Not paused or cancelled, no microtask scheduled.
  static const int _stateReadyToSend = 0;

  /// Set when a microtask is scheduled, and not cancelled.
  static const int _stateScheduled = 1;

  /// State set when done event sent or subscription cancelled.
  ///
  /// Any negative value counts as done, so we can safely subtract
  /// [_stateScheduled] or [_statePausedOnce] without affecting
  /// being cancelled.
  ///
  /// Never considered paused in this state, may still be scheduled,
  /// and [_onDone] is always set to `null`.
  static const int _stateDone = -1;

  /// Added for each pause while not done or cancelled, subtracted on resume.
  ///
  /// Subscription is paused when state is at least `_statePausedOnce`.
  static const int _statePausedOnce = 2;

  int _state;
  final Zone _zone;
  void Function()? _onDone;

  _DoneStreamSubscription(void Function()? onDone)
    : _zone = Zone.current,
      _state = _stateScheduled {
    scheduleMicrotask(_onMicrotask);
    if (onDone != null) {
      _onDone = _zone.registerCallback(onDone);
    }
  }

  bool get isPaused => _state >= _statePausedOnce;

  /// True after being cancelled, or after delivering done event.
  static bool _isDone(int state) => state < 0;

  static int _incrementPauseCount(int state) => state + _statePausedOnce;
  static int _decrementPauseCount(int state) => state - _statePausedOnce;

  void onData(void handleData(T data)?) {}

  void onError(Function? handleError) {}

  void onDone(void handleDone()?) {
    if (!_isDone(_state)) {
      if (handleDone != null) handleDone = _zone.registerCallback(handleDone);
      _onDone = handleDone;
    }
  }

  void pause([Future<void>? resumeSignal]) {
    if (!_isDone(_state)) {
      _state = _incrementPauseCount(_state);
      if (resumeSignal != null) resumeSignal.whenComplete(resume);
    }
  }

  void resume() {
    var resumeState = _decrementPauseCount(_state);
    if (resumeState < 0) return; // Wasn't paused.
    if (resumeState == _stateReadyToSend) {
      // No longer paused, and not already scheduled.
      _state = _stateScheduled;
      scheduleMicrotask(_onMicrotask);
    } else {
      _state = resumeState;
    }
  }

  Future cancel() {
    _state = _stateDone;
    _onDone = null;
    return Future._nullFuture;
  }

  Future<E> asFuture<E>([E? futureValue]) {
    E resultValue;
    if (futureValue == null) {
      if (!typeAcceptsNull<E>()) {
        throw ArgumentError.notNull("futureValue");
      }
      resultValue = futureValue as dynamic;
    } else {
      resultValue = futureValue;
    }
    _Future<E> result = _Future<E>();
    if (!_isDone(_state)) {
      _onDone = _zone.registerCallback(() {
        result._completeWithValue(resultValue);
      });
    }
    return result;
  }

  void _onMicrotask() {
    var unscheduledState = _state - _stateScheduled;
    if (unscheduledState == _stateReadyToSend) {
      // Send the done event.
      _state = _stateDone;
      if (_onDone case var doneHandler?) {
        _onDone = null;
        _zone.runGuarded(doneHandler);
      }
    } else {
      // Paused or cancelled.
      _state = unscheduledState;
    }
  }
}

class _AsBroadcastStream<T> extends Stream<T> {
  final Stream<T> _source;
  final _BroadcastCallback<T>? _onListenHandler;
  final _BroadcastCallback<T>? _onCancelHandler;
  final Zone _zone;

  _AsBroadcastStreamController<T>? _controller;
  StreamSubscription<T>? _subscription;

  _AsBroadcastStream(
    this._source,
    void onListenHandler(StreamSubscription<T> subscription)?,
    void onCancelHandler(StreamSubscription<T> subscription)?,
  ) : _onListenHandler =
          onListenHandler == null
              ? null
              : Zone.current.registerUnaryCallback<void, StreamSubscription<T>>(
                onListenHandler,
              ),
      _onCancelHandler =
          onCancelHandler == null
              ? null
              : Zone.current.registerUnaryCallback<void, StreamSubscription<T>>(
                onCancelHandler,
              ),
      _zone = Zone.current {
    _controller = new _AsBroadcastStreamController<T>(_onListen, _onCancel);
  }

  bool get isBroadcast => true;

  StreamSubscription<T> listen(
    void onData(T data)?, {
    Function? onError,
    void onDone()?,
    bool? cancelOnError,
  }) {
    var controller = _controller;
    if (controller == null || controller.isClosed) {
      // Return a dummy subscription backed by nothing, since
      // it will only ever send one done event.
      return new _DoneStreamSubscription<T>(onDone);
    }
    _subscription ??= _source.listen(
      controller.add,
      onError: controller.addError,
      onDone: controller.close,
    );
    return controller._subscribe(
      onData,
      onError,
      onDone,
      cancelOnError ?? false,
    );
  }

  void _onCancel() {
    var controller = _controller;
    bool shutdown = (controller == null) || controller.isClosed;
    var cancelHandler = _onCancelHandler;
    if (cancelHandler != null) {
      _zone.runUnary(cancelHandler, new _BroadcastSubscriptionWrapper<T>(this));
    }
    if (shutdown) {
      var subscription = _subscription;
      if (subscription != null) {
        subscription.cancel();
        _subscription = null;
      }
    }
  }

  void _onListen() {
    var listenHandler = _onListenHandler;
    if (listenHandler != null) {
      _zone.runUnary(listenHandler, new _BroadcastSubscriptionWrapper<T>(this));
    }
  }

  // Methods called from _BroadcastSubscriptionWrapper.
  void _cancelSubscription() {
    // Called by [_controller] when it has no subscribers left.
    var subscription = _subscription;
    if (subscription != null) {
      _subscription = null;
      _controller = null; // Marks the stream as no longer listenable.
      subscription.cancel();
    }
  }

  void _pauseSubscription(Future<void>? resumeSignal) {
    _subscription?.pause(resumeSignal);
  }

  void _resumeSubscription() {
    _subscription?.resume();
  }

  bool get _isSubscriptionPaused {
    return _subscription?.isPaused ?? false;
  }
}

/// Wrapper for subscription that disallows changing handlers.
class _BroadcastSubscriptionWrapper<T> implements StreamSubscription<T> {
  final _AsBroadcastStream _stream;

  _BroadcastSubscriptionWrapper(this._stream);

  void onData(void handleData(T data)?) {
    throw new UnsupportedError(
      "Cannot change handlers of asBroadcastStream source subscription.",
    );
  }

  void onError(Function? handleError) {
    throw new UnsupportedError(
      "Cannot change handlers of asBroadcastStream source subscription.",
    );
  }

  void onDone(void handleDone()?) {
    throw new UnsupportedError(
      "Cannot change handlers of asBroadcastStream source subscription.",
    );
  }

  void pause([Future<void>? resumeSignal]) {
    _stream._pauseSubscription(resumeSignal);
  }

  void resume() {
    _stream._resumeSubscription();
  }

  Future cancel() {
    _stream._cancelSubscription();
    return Future._nullFuture;
  }

  bool get isPaused {
    return _stream._isSubscriptionPaused;
  }

  Future<E> asFuture<E>([E? futureValue]) {
    throw new UnsupportedError(
      "Cannot change handlers of asBroadcastStream source subscription.",
    );
  }
}

/// Simple implementation of [StreamIterator].
///
/// Pauses the stream between calls to [moveNext].
class _StreamIterator<T> implements StreamIterator<T> {
  // The stream iterator is always in one of five states.
  // The value of the [_stateData] field depends on the state.
  //
  // When `_subscription == null`, `_stateData != null`, and not listened yet:
  // The stream iterator has been created, but [moveNext] has not been called
  // yet. The [_stateData] field contains the stream to listen to on the first
  // call to [moveNext] and [current] returns `null`.
  //
  // When `_subscription == null`, `_stateData != null`, during `listen` call.
  // The `listen` call has not returned a subscription yet.
  // The `_stateData` contains the future returned by the first [moveNext]
  // call. This state is only detected inside the stream event callbacks,
  // since it's the only case where they can get called while `_subscription`
  // is `null`. (A well-behaved stream should not be emitting events during
  // the `listen` call, but some do anyway). The [current] is `null`.
  //
  // When `_subscription != null` and `!_hasValue`:
  // The user has called [moveNext] and the iterator is waiting for the next
  // event. The [_stateData] field contains the [_Future] returned by the
  // [_moveNext] call and [current] returns `null.`
  //
  // When `_subscription != null` and `_hasValue`:
  // The most recent call to [moveNext] has completed with a `true` value
  // and [current] provides the value of the data event.
  // The [_stateData] field contains the [current] value.
  //
  // When `_subscription == null` and `_stateData == null`:
  // The stream has completed or been canceled using [cancel].
  // The stream completes on either a done event or an error event.
  // The last call to [moveNext] has completed with `false` and [current]
  // returns `null`.

  /// Subscription being listened to.
  ///
  /// Set to `null` when the stream subscription is done or canceled.
  StreamSubscription<T>? _subscription;

  /// Data value depending on the current state.
  ///
  /// Before first call to [moveNext]: The stream to listen to.
  ///
  /// After calling [moveNext] but before the returned future completes:
  /// The returned future.
  ///
  /// After calling [moveNext] and the returned future has completed
  /// with `true`: The value of [current].
  ///
  /// After calling [moveNext] and the returned future has completed
  /// with `false`, or after calling [cancel]: `null`.
  @pragma("vm:entry-point")
  Object? _stateData;

  /// Whether the iterator is between calls to `moveNext`.
  /// This will usually cause the [_subscription] to be paused, but as an
  /// optimization, we only pause after the [moveNext] future has been
  /// completed.
  @pragma("vm:entry-point")
  bool _hasValue = false;

  _StreamIterator(final Stream<T> stream)
    : _stateData = checkNotNullable(stream, "stream");

  T get current {
    if (_hasValue) return _stateData as dynamic;
    return null as dynamic;
  }

  Future<bool> moveNext() {
    var subscription = _subscription;
    if (subscription != null) {
      if (_hasValue) {
        var future = new _Future<bool>();
        _stateData = future;
        _hasValue = false;
        subscription.resume();
        return future;
      }
      throw new StateError("Already waiting for next.");
    }
    return _initializeOrDone();
  }

  /// Called if there is no active subscription when [moveNext] is called.
  ///
  /// Either starts listening on the stream if this is the first call to
  /// [moveNext], or returns a `false` future because the stream has already
  /// ended.
  Future<bool> _initializeOrDone() {
    assert(_subscription == null);
    var stateData = _stateData;
    if (stateData != null) {
      Stream<T> stream = stateData as dynamic;
      var future = new _Future<bool>();
      _stateData = future;
      // The `listen` call may invoke user code, and it might try to emit
      // events.
      // We ignore data events during `listen`, but error or done events
      // are used to asynchronously complete the future and set `_stateData`
      // to null.
      // This ensures that we do no other user-code callbacks during `listen`
      // than the `onListen` itself. If that code manages to call `moveNext`
      // again on this iterator, then we will get here and fail when the
      // `_stateData` is a future instead of a stream.
      var subscription = stream.listen(
        _onData,
        onError: _onError,
        onDone: _onDone,
        cancelOnError: true,
      );
      if (_stateData != null) {
        _subscription = subscription;
      }
      return future;
    }
    return Future._falseFuture;
  }

  Future cancel() {
    var subscription = _subscription;
    var stateData = _stateData;
    _stateData = null;
    if (subscription != null) {
      _subscription = null;
      if (!_hasValue) {
        _Future<bool> future = stateData as dynamic;
        future._asyncComplete(false);
      } else {
        _hasValue = false;
      }
      return subscription.cancel();
    }
    return Future._nullFuture;
  }

  void _onData(T data) {
    // Ignore events sent during the `listen` call
    // (which can happen if misusing synchronous broadcast stream controllers),
    // or after `cancel` or `done` (for *really* misbehaving streams).
    if (_subscription == null) return;
    _Future<bool> moveNextFuture = _stateData as dynamic;
    _stateData = data;
    _hasValue = true;
    moveNextFuture._complete(true);
    if (_hasValue) _subscription?.pause();
  }

  void _onError(Object error, StackTrace stackTrace) {
    var subscription = _subscription;
    _Future<bool> moveNextFuture = _stateData as dynamic;
    _subscription = null;
    _stateData = null;
    if (subscription != null) {
      moveNextFuture._completeError(error, stackTrace);
    } else {
      // Event delivered during `listen` call.
      moveNextFuture._asyncCompleteError(error, stackTrace);
    }
  }

  void _onDone() {
    var subscription = _subscription;
    _Future<bool> moveNextFuture = _stateData as dynamic;
    _subscription = null;
    _stateData = null;
    if (subscription != null) {
      moveNextFuture._completeWithValue(false);
    } else {
      // Event delivered during `listen` call.
      moveNextFuture._asyncCompleteWithValue(false);
    }
  }
}

/// An empty broadcast stream, sending a done event as soon as possible.
class _EmptyStream<T> extends Stream<T> {
  const _EmptyStream({bool broadcast = true}) : isBroadcast = broadcast;
  final bool isBroadcast;
  StreamSubscription<T> listen(
    void Function(T data)? onData, {
    Function? onError,
    void Function()? onDone,
    bool? cancelOnError,
  }) {
    return _DoneStreamSubscription<T>(onDone);
  }
}

/// A stream which creates a new controller for each listener.
class _MultiStream<T> extends Stream<T> {
  final bool isBroadcast;

  /// The callback called for each listen.
  final void Function(MultiStreamController<T>) _onListen;

  _MultiStream(this._onListen, this.isBroadcast);

  StreamSubscription<T> listen(
    void onData(T event)?, {
    Function? onError,
    void onDone()?,
    bool? cancelOnError,
  }) {
    var controller = _MultiStreamController<T>();
    controller.onListen = () {
      _onListen(controller);
    };
    return controller._subscribe(
      onData,
      onError,
      onDone,
      cancelOnError ?? false,
    );
  }
}

class _MultiStreamController<T> extends _AsyncStreamController<T>
    implements MultiStreamController<T> {
  _MultiStreamController() : super(null, null, null, null);

  void addSync(T data) {
    if (!_mayAddEvent) throw _badEventState();
    if (hasListener) _subscription._add(data);
  }

  void addErrorSync(Object error, [StackTrace? stackTrace]) {
    if (!_mayAddEvent) throw _badEventState();
    if (hasListener) {
      _subscription._addError(error, stackTrace ?? StackTrace.empty);
    }
  }

  void closeSync() {
    if (isClosed) return;
    if (!_mayAddEvent) throw _badEventState();
    _state |= _StreamController._STATE_CLOSED;
    if (hasListener) _subscription._close();
  }

  Stream<T> get stream {
    throw UnsupportedError("Not available");
  }
}
