// 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:async';

import 'aggregate_sample.dart';
import 'common_callbacks.dart';
import 'from_handlers.dart';
import 'rate_limit.dart';

/// Alternatives to [asyncMap].
///
/// The built in [asyncMap] will not overlap execution of the passed callback,
/// and every event will be sent to the callback individually.
///
/// - [asyncMapBuffer] prevents the callback from overlapping execution and
///   collects events while it is executing to process in batches.
/// - [asyncMapSample] prevents overlapping execution and discards events while
///   it is executing.
/// - [concurrentAsyncMap] allows overlap and removes ordering guarantees.
extension AsyncMap<T> on Stream<T> {
  /// Like [asyncMap] but events are buffered until previous events have been
  /// processed by [convert].
  ///
  /// If this stream is a broadcast stream the result will be as well.
  /// When used with a broadcast stream behavior also differs from [asyncMap] in
  /// that the [convert] function is only called once per event, rather than
  /// once per listener per event.
  ///
  /// The first event from this stream is always passed to [convert] as a
  /// list with a single element.
  /// After that, events are buffered until the previous Future returned from
  /// [convert] has completed.
  ///
  /// Errors from this stream are forwarded directly to the result stream.
  /// Errors during the conversion are also forwarded to the result stream and
  /// are considered completing work so the next values are let through.
  ///
  /// The result stream will not close until this stream closes and all pending
  /// conversions have finished.
  Stream<S> asyncMapBuffer<S>(Future<S> Function(List<T>) convert) {
    var workFinished = StreamController<void>()
      // Let the first event through.
      ..add(null);
    return buffer(workFinished.stream)._asyncMapThen(convert, workFinished.add);
  }

  /// Like [asyncMap] but events are discarded while work is happening in
  /// [convert].
  ///
  /// If this stream is a broadcast stream the result will be as well.
  /// When used with a broadcast stream behavior also differs from [asyncMap] in
  /// that the [convert] function is only called once per event, rather than
  /// once per listener per event.
  ///
  /// If no work is happening when an event is emitted it will be immediately
  /// passed to [convert]. If there is ongoing work when an event is emitted it
  /// will be held until the work is finished. New events emitted will replace a
  /// pending event.
  ///
  /// Errors from this stream are forwarded directly to the result stream.
  /// Errors during the conversion are also forwarded to the result stream and
  /// are considered completing work so the next values are let through.
  ///
  /// The result stream will not close until this stream closes and all pending
  /// conversions have finished.
  Stream<S> asyncMapSample<S>(Future<S> Function(T) convert) {
    var workFinished = StreamController<void>()
      // Let the first event through.
      ..add(null);
    return aggregateSample(
            trigger: workFinished.stream,
            aggregate: _dropPrevious,
            longPoll: true,
            onEmpty: ignoreArgument)
        ._asyncMapThen(convert, workFinished.add);
  }

  /// Like [asyncMap] but the [convert] callback may be called for an element
  /// before processing for the previous element is finished.
  ///
  /// Events on the result stream will be emitted in the order that [convert]
  /// completed which may not match the order of this stream.
  ///
  /// If this stream is a broadcast stream the result will be as well.
  /// When used with a broadcast stream behavior also differs from [asyncMap] in
  /// that the [convert] function is only called once per event, rather than
  /// once per listener per event. The [convert] callback won't be called for
  /// events while a broadcast stream has no listener.
  ///
  /// Errors from [convert] or this stream are forwarded directly to the
  /// result stream.
  ///
  /// The result stream will not close until this stream closes and all pending
  /// conversions have finished.
  Stream<S> concurrentAsyncMap<S>(FutureOr<S> Function(T) convert) {
    var valuesWaiting = 0;
    var sourceDone = false;
    return transformByHandlers(onData: (element, sink) {
      valuesWaiting++;
      () async {
        try {
          sink.add(await convert(element));
        } catch (e, st) {
          sink.addError(e, st);
        }
        valuesWaiting--;
        if (valuesWaiting <= 0 && sourceDone) sink.close();
      }();
    }, onDone: (sink) {
      sourceDone = true;
      if (valuesWaiting <= 0) sink.close();
    });
  }

  /// Like [Stream.asyncMap] but the [convert] is only called once per event,
  /// rather than once per listener, and [then] is called after completing the
  /// work.
  Stream<S> _asyncMapThen<S>(
      Future<S> Function(T) convert, void Function(void) then) {
    Future<void>? pendingEvent;
    return transformByHandlers(onData: (event, sink) {
      pendingEvent =
          convert(event).then(sink.add).catchError(sink.addError).then(then);
    }, onDone: (sink) {
      if (pendingEvent != null) {
        pendingEvent!.then((_) => sink.close());
      } else {
        sink.close();
      }
    });
  }
}

T _dropPrevious<T>(T event, _) => event;
