// 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;
    _microtaskEntryCallback(entry)();
  }
}

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);
  _beforeScheduleMicrotaskCallback();
  _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);
  _beforeSchedulePriorityCallback();
  _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;
    }
  }
}

// Overridden by VM.
@pragma("dart2js:prefer-inline")
@pragma("dart2wasm:prefer-inline")
void _beforeSchedulePriorityCallback() {}

@pragma("dart2js:prefer-inline")
@pragma("dart2wasm:prefer-inline")
void _beforeScheduleMicrotaskCallback() {}

@pragma("dart2js:prefer-inline")
@pragma("dart2wasm:prefer-inline")
void Function() _microtaskEntryCallback(_AsyncCallbackEntry entry) =>
    entry.callback;

/// 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));
}

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