// Copyright (c) 2013, 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;

typedef void _AsyncCallback();

class _AsyncCallbackEntry {
  final _AsyncCallback callback;
  _AsyncCallbackEntry? next;
  _AsyncCallbackEntry(this.callback);
}

/// Head of single linked list of pending callbacks.
_AsyncCallbackEntry? _nextCallback;

/// Tail of single linked list of pending callbacks.
_AsyncCallbackEntry? _lastCallback;

/// Tail of priority callbacks added by the currently executing callback.
///
/// Priority callbacks are put at the beginning of the
/// callback queue, so that if one callback schedules more than one
/// priority callback, they are still enqueued in scheduling order.
_AsyncCallbackEntry? _lastPriorityCallback;

/// Whether we are currently inside the callback loop.
///
/// If we are inside the loop, we never need to schedule the loop,
/// even if adding a first element.
bool _isInCallbackLoop = false;

void _microtaskLoop() {
  for (var entry = _nextCallback; entry != null; entry = _nextCallback) {
    _lastPriorityCallback = null;
    var next = entry.next;
    _nextCallback = next;
    if (next == null) _lastCallback = null;
    if (const bool.fromEnvironment("dart.vm.product") ||
        !_MicrotaskMirrorQueue._shouldProfileMicrotasks) {
      (entry.callback)();
    } else {
      final callbackStartTime = Timeline.now;
      (entry.callback)();
      final callbackEndTime = Timeline.now;
      _MicrotaskMirrorQueue._onAsyncCallbackComplete(
        callbackStartTime,
        callbackEndTime,
      );
    }
  }
}

void _startMicrotaskLoop() {
  _isInCallbackLoop = true;
  try {
    // Moved to separate function because try-finally prevents
    // good optimization.
    _microtaskLoop();
  } finally {
    _lastPriorityCallback = null;
    _isInCallbackLoop = false;
    if (_nextCallback != null) {
      _AsyncRun._scheduleImmediate(_startMicrotaskLoop);
    }
  }
}

/// Schedules a callback to be called as a microtask.
///
/// The microtask is called after all other currently scheduled
/// microtasks, but as part of the current system event.
void _scheduleAsyncCallback(_AsyncCallback callback) {
  _AsyncCallbackEntry newEntry = _AsyncCallbackEntry(callback);
  if (!const bool.fromEnvironment("dart.vm.product") &&
      _MicrotaskMirrorQueue._shouldProfileMicrotasks) {
    _MicrotaskMirrorQueue._onScheduleAsyncCallback();
  }
  _AsyncCallbackEntry? lastCallback = _lastCallback;
  if (lastCallback == null) {
    _nextCallback = _lastCallback = newEntry;
    if (!_isInCallbackLoop) {
      _AsyncRun._scheduleImmediate(_startMicrotaskLoop);
    }
  } else {
    lastCallback.next = newEntry;
    _lastCallback = newEntry;
  }
}

/// Schedules a callback to be called before all other currently scheduled ones.
///
/// This callback takes priority over existing scheduled callbacks.
/// It is only used internally to give higher priority to error reporting.
///
/// Is always run in the root zone.
void _schedulePriorityAsyncCallback(_AsyncCallback callback) {
  if (_nextCallback == null) {
    _scheduleAsyncCallback(callback);
    _lastPriorityCallback = _lastCallback;
    return;
  }
  _AsyncCallbackEntry entry = _AsyncCallbackEntry(callback);
  if (!const bool.fromEnvironment("dart.vm.product") &&
      _MicrotaskMirrorQueue._shouldProfileMicrotasks) {
    _MicrotaskMirrorQueue._onSchedulePriorityAsyncCallback();
  }
  _AsyncCallbackEntry? lastPriorityCallback = _lastPriorityCallback;
  if (lastPriorityCallback == null) {
    entry.next = _nextCallback;
    _nextCallback = _lastPriorityCallback = entry;
  } else {
    var next = lastPriorityCallback.next;
    entry.next = next;
    lastPriorityCallback.next = entry;
    _lastPriorityCallback = entry;
    if (next == null) {
      _lastCallback = entry;
    }
  }
}

/// Runs a function asynchronously.
///
/// Callbacks registered through this function are always executed in order and
/// are guaranteed to run before other asynchronous events (like [Timer] events,
/// or DOM events).
///
/// **Warning:** it is possible to starve the DOM by registering asynchronous
/// callbacks through this method. For example the following program runs
/// the callbacks without ever giving the Timer callback a chance to execute:
/// ```dart
/// main() {
///   Timer.run(() { print("executed"); });  // Will never be executed.
///   foo() {
///     scheduleMicrotask(foo);  // Schedules [foo] in front of other events.
///   }
///   foo();
/// }
/// ```
/// ## Other resources
///
/// * [The Event Loop and Dart](https://dart.dev/articles/event-loop/):
/// Learn how Dart handles the event queue and microtask queue, so you can write
/// better asynchronous code with fewer surprises.
@pragma('vm:entry-point', 'call')
void scheduleMicrotask(void Function() callback) {
  _Zone currentZone = Zone._current;
  if (identical(_rootZone, currentZone)) {
    // No need to bind the callback. We know that the root's scheduleMicrotask
    // will be invoked in the root zone.
    _rootScheduleMicrotask(null, null, _rootZone, callback);
    return;
  }
  _ZoneFunction implementation = currentZone._scheduleMicrotask;
  if (identical(_rootZone, implementation.zone) &&
      _rootZone.inSameErrorZone(currentZone)) {
    _rootScheduleMicrotask(
      null,
      null,
      currentZone,
      currentZone.registerCallback(callback),
    );
    return;
  }
  Zone.current.scheduleMicrotask(Zone.current.bindCallbackGuarded(callback));
}

@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
abstract final class _MicrotaskMirrorQueue {
  // This will be set to true by the native runtime's
  // `DartUtils::PrepareAsyncLibrary` when the CLI flag `--profile-microtasks`
  // is set.
  @pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
  static bool _shouldProfileMicrotasks = false;

  // The following methods are only implemented for the native runtime. Those
  // implementations are in
  // `sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart`.
  static void _onScheduleAsyncCallback() {}
  static void _onSchedulePriorityAsyncCallback() {}
  static void _onAsyncCallbackComplete(int startTime, int endTime) {}
}

class _AsyncRun {
  /// Schedule the given callback before any other event in the event-loop.
  external static void _scheduleImmediate(void Function() callback);
}
