// Copyright 2026 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SRC_DAWN_NODE_STANDALONE_EVENTLOOP_H_
#define SRC_DAWN_NODE_STANDALONE_EVENTLOOP_H_

#include <chrono>
#include <cstdint>
#include <deque>
#include <optional>
#include <thread>
#include <utility>

#include "absl/container/btree_map.h"
#include "absl/functional/any_invocable.h"

namespace v8 {
class Isolate;
class Platform;
}  // namespace v8

namespace dawn::node::standalone {

// A Node.js-shaped event loop. Each iteration runs the timers that have come due, then the
// immediates that were already queued when the phase began.
//
// Every task runs inside a handle scope, with the microtask queue drained afterwards, so a task is
// free to call into JavaScript. An uncaught exception is printed and stops the loop with exit code
// 1, which is why the loop rather than its caller owns the exit code.
//
// Node's phase order is not an implementation detail we are free to change. `setTimeout` and
// `setImmediate` callbacks observe it, and Dawn's AsyncRunner relies on the check phase deferring
// work to the next iteration; see the comment on RunOneIteration(). The order is documented at
// https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick
//
// Every method must be called on the thread that constructed the loop, which is the thread the
// isolate runs on. Tasks only ever arrive by way of a JavaScript call - the timer polyfills, and
// AsyncRunner, which posts by calling the global setImmediate() rather than by reaching in here -
// and a JavaScript call is already confined to that thread. Debug builds check this.
class EventLoop {
  public:
    using Task = absl::AnyInvocable<void()>;
    using Clock = std::chrono::steady_clock;
    using TimePoint = Clock::time_point;
    using Duration = Clock::duration;
    using TimerId = uint64_t;

    // What a single iteration found to do.
    enum class IterationResult {
        // At least one task ran. More may already be ready.
        kRanTasks,
        // Nothing was ready to run. The caller may wait until NextDueTime().
        kIdle,
        // Stop() has been called.
        kStopped,
    };

    // `isolate` must be entered, with a context entered, whenever a task runs. `platform` is the
    // one the isolate was created with; the loop pumps its foreground work each iteration. Neither
    // is owned, and both must outlive the loop.
    EventLoop(v8::Isolate* isolate, v8::Platform* platform);
    virtual ~EventLoop();

    EventLoop(const EventLoop&) = delete;
    EventLoop& operator=(const EventLoop&) = delete;

    // Queues `task` for the next check phase. Backs setImmediate().
    void PostTask(Task task);

    // Queues `task` to run once `delay` has elapsed, and returns an identifier that
    // CancelDelayedTask() accepts. Backs setTimeout() and setInterval().
    TimerId PostDelayedTask(Task task, Duration delay);

    // Drops a delayed task that has not run yet. Unknown and already-run identifiers are ignored,
    // because clearTimeout() on an expired timer is not an error.
    void CancelDelayedTask(TimerId id);

    // Runs one timers phase followed by one check phase.
    IterationResult RunOneIteration();

    // Runs iterations until Stop() is called or there is no work left to wait for.
    void Run();

    // Asks the loop to finish. Takes effect between tasks. Once stopped, later calls do not
    // overwrite the exit code. Backs process.exit().
    void Stop(int exit_code);

    bool stopped() const { return stopped_; }
    int exit_code() const { return exit_code_; }

    // When the earliest pending timer comes due, or nullopt when no timer is pending.
    std::optional<TimePoint> NextDueTime() const {
        if (timers_.empty()) {
            return std::nullopt;
        }
        return timers_.begin()->first.due;
    }

  protected:
    // The loop's only reading of the clock. Virtual so that tests can control the passage of time
    // without depending on real time; every other seam this class used to have is gone.
    virtual TimePoint Now() const;

  private:
    // Runs a single task and then drains the microtask queue, mirroring what a browser or Node.js
    // does between task callbacks. An uncaught exception is reported and stops the loop.
    void RunTask(Task task);

    // Blocks until `due`, or until it is worth looking for work again. Capped so that
    // PumpEngineTasks() gets a turn while a distant timer is pending.
    void WaitUntil(TimePoint due);

    // Runs any foreground work V8 has queued for this thread, reporting whether it ran any.
    bool PumpEngineTasks();

    // Checks, in debug builds, that the caller is on the thread that constructed the loop.
    void AssertOnLoopThread() const;

    // Orders timers by the time they come due, and timers that share a deadline by the order they
    // were posted, since identifiers are handed out in that order.
    struct TimerKey {
        TimePoint due;
        TimerId id;
        auto operator<=>(const TimerKey&) const = default;
    };

    v8::Isolate* const isolate_;
    v8::Platform* const platform_;
    // The thread the loop belongs to. Only read by AssertOnLoopThread().
    const std::thread::id thread_id_ = std::this_thread::get_id();
    // Tasks waiting for the next check phase, in the order they were posted.
    std::deque<Task> immediates_;
    absl::btree_map<TimerKey, Task> timers_;
    TimerId next_timer_id_ = 1;
    bool stopped_ = false;
    int exit_code_ = 0;
};

}  // namespace dawn::node::standalone

#endif  // SRC_DAWN_NODE_STANDALONE_EVENTLOOP_H_
