#ifdef WITH_RIVE_SCRIPTING_WASM

#include "rive/wasm/wasm_workers.hpp"
#include "rive/async/job_pool.hpp"
#include "rive/wasm/wasm_jobs.hpp"
#include "rive/wasm/wasm_lane_policy.hpp"

#ifndef __EMSCRIPTEN__
#include "wasm_export.h"
#else
#include <emscripten/em_js.h>
#include <emscripten/emscripten.h>
#endif

#include <algorithm>
#include <condition_variable>
#include <cstdio>
#include <mutex>
#include <thread>

using namespace rive;

namespace
{
using Clock = std::chrono::steady_clock;
constexpr uint32_t kStopGraceMs = lane_timing::kWorkerStopGraceMs;
} // namespace

// --- the pool ----------------------------------------------------------------

#if RIVE_POOL_THREADS()
namespace
{
constexpr auto kSlice = std::chrono::milliseconds(lane_timing::kWorkerSliceMs);
// A thread the pool no longer needs lingers this long, so a worker that keeps
// taking long steps does not churn threads.
constexpr auto kRetireAfter = std::chrono::seconds(1);
} // namespace

// A few threads stepping every VM's workers, each taking whichever is due.
class rive::WasmWorkerPool
{
public:
  // Leaked, as its threads may outlive static destructors.
  static WasmWorkerPool& instance()
  {
    static WasmWorkerPool* pool = new WasmWorkerPool();
    return *pool;
  }

  // Every worker's signal waits watch it, so any notify reaches the pool.
  WakeWord& wakeWord() { return m_wake; }
  std::mutex& mutex() { return m_mutex; }

  void add(rcp<WasmWorker> worker)
  {
    bool first;
    {
      std::lock_guard<std::mutex> lock(m_mutex);
      m_workers.push_back(std::move(worker));
      first = !m_supervising;
      m_supervising = true;
    }
    if (first)
    {
      JobPool::makeThread([this]() { superviseMain(); }).detach();
    }
    m_supervise.notify_one();
    m_wake.wake();
  }

  // Takes a worker no runner claimed or began, for its stop to end it at
  // once; false when a runner has it.
  bool takeUnstarted(WasmWorker* worker)
  {
    rcp<WasmWorker> taken;
    std::lock_guard<std::mutex> lock(m_mutex);
    if (worker->m_claimed || worker->m_begun || worker->over())
    {
      return false;
    }
    worker->m_claimed = true;
    taken = eraseLocked(worker);
    return true;
  }

  void join(WasmWorker* worker, Clock::time_point deadline)
  {
    while (!worker->over())
    {
      if (Clock::now() < deadline)
      {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
        continue;
      }
#ifdef __EMSCRIPTEN__
      // The page's thread must not block, so a worker still running ends on
      // its own thread, if metered at its first fuel check past the grace.
      return;
#else
      bool idle;
      rcp<WasmWorker> taken;
      {
        std::lock_guard<std::mutex> lock(m_mutex);
        // A runner may have ended and dropped it since the check.
        if (worker->over())
        {
          return;
        }
        idle = !worker->m_claimed;
        if (idle)
        {
          worker->m_claimed = true;
          taken = eraseLocked(worker);
        }
      }
      // No pool thread got to its stop in time, so it ends here.
      if (idle)
      {
        worker->end();
        return;
      }
      // A worker that never awaits again never sees the stop, and one
      // with no instance yet has no call to interrupt.
      while (!worker->over())
      {
        worker->interruptCall();
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
      }
      return;
#endif
    }
  }

  void configure(uint32_t threads, uint32_t promotedPerVM)
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    if (threads == 0)
    {
      setDefaults();
    }
    else
    {
      m_threads = threads;
      m_promotedPerVM = promotedPerVM;
    }
    m_resizing = true;
    m_wake.wake();
    m_runnersLeft.wait(lock, [this]() { return m_runners.empty(); });
    m_resizing = false;
    lock.unlock();
    m_supervise.notify_one();
  }

private:
  enum class Slice
  {
    idle,
    timing,
    promoted,
    // Past the slice with every promotion taken, it keeps its thread.
    kept,
  };
  struct Runner
  {
    WasmWorker* stepping = nullptr;
    Clock::time_point stepStart;
    Slice slice = Slice::idle;
  };

  WasmWorkerPool() { setDefaults(); }

  void setDefaults()
  {
#ifdef __EMSCRIPTEN__
    // Browser threads come from a small pool all of librive shares.
    m_threads = 2;
    m_promotedPerVM = 2;
#else
    uint32_t hardware = std::thread::hardware_concurrency();
    m_threads = std::min<uint32_t>(hardware > 2 ? hardware - 1 : 1, 4);
    m_promotedPerVM = 4;
#endif
    if (uint32_t threads = ScriptingLimits::get().workerThreads)
    {
      m_threads = threads;
    }
  }

  void runnerMain(Runner* runner)
  {
#ifndef __EMSCRIPTEN__
    ensureWasmThreadEnv();
#endif
    Clock::time_point idleSince = Clock::now();
    std::unique_lock<std::mutex> lock(m_mutex);
    while (!m_resizing)
    {
      // Read before the scan, so a wake landing during it ends the
      // wait below at once.
      uint32_t seen = m_wake.value();
      Clock::time_point now = Clock::now();
      Clock::time_point next = Clock::time_point::max();
      if (rcp<WasmWorker> worker = takeLocked(runner, now, next))
      {
        runner->stepping = worker.get();
        runner->stepStart = now;
        runner->slice = Slice::timing;
        bool timeIt = m_superviseIdle;
        lock.unlock();
        if (timeIt)
        {
          m_supervise.notify_one();
        }
        bool ended = worker->run() == WasmWorker::Step::done;
        lock.lock();
        if (runner->slice == Slice::promoted && !worker->m_promoted)
        {
          worker->m_promoted = true;
          worker->log(
              "worker promoted to its own thread: a step "
              "ran past " +
              std::to_string(kSlice.count()) + " ms without awaiting");
        }
        // A stop this step never saw arms its grace again where it
        // is delivered.
        if (!ended && worker->stopping() && !worker->m_stopDelivered)
        {
          worker->dropInterrupt();
        }
        // What a long step held frees for one kept on its thread.
        bool freed = runner->slice != Slice::timing;
        runner->stepping = nullptr;
        runner->slice = Slice::idle;
        worker->m_claimed = false;
        rcp<WasmWorker> erased = ended ? eraseLocked(worker.get()) : nullptr;
        // Its last reference may go here, which must not happen
        // under the lock.
        lock.unlock();
        if (freed)
        {
          m_supervise.notify_one();
        }
        erased = nullptr;
        worker = nullptr;
        lock.lock();
        idleSince = Clock::now();
        continue;
      }
      if ((m_workers.empty() || servingLocked() > m_threads) &&
          !pinsLocked(runner))
      {
        Clock::time_point retire = idleSince + kRetireAfter;
        if (now >= retire)
        {
          break;
        }
        next = std::min(next, retire);
      }
      lock.unlock();
      m_wake.wait(seen, next);
      lock.lock();
    }
    m_runners.erase(std::find_if(
        m_runners.begin(),
        m_runners.end(),
        [runner](const auto& other) { return other.get() == runner; }));
    m_runnersLeft.notify_all();
    m_supervise.notify_one();
  }

  // Promotes long steps on time and keeps the pool at its size, whether or
  // not a runner is idle or a host advances.
  void superviseMain()
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    for (;;)
    {
      Clock::time_point next = Clock::time_point::max();
      std::vector<Runner*> started = superviseLocked(Clock::now(), next);
      if (!started.empty())
      {
        lock.unlock();
        start(started);
        lock.lock();
        continue;
      }
      if (next == Clock::time_point::max())
      {
        m_superviseIdle = true;
        m_supervise.wait(lock);
        m_superviseIdle = false;
      }
      else
      {
        m_supervise.wait_until(lock, next);
      }
    }
  }

  // The next due worker this runner may step, taken in turn so none
  // starves; lowers next to the earliest timeout of the rest.
  rcp<WasmWorker> takeLocked(
      Runner* runner,
      Clock::time_point now,
      Clock::time_point& next)
  {
    size_t count = m_workers.size();
    for (size_t i = 0; i < count; i++)
    {
      size_t at = (m_next + i) % count;
      WasmWorker* worker = m_workers[at].get();
      if (worker->m_claimed ||
          (worker->m_pin != nullptr && worker->m_pin != runner) ||
#ifdef __EMSCRIPTEN__
          (worker->m_pin == nullptr && pinsLocked(runner) &&
           mayOwnRunnerLocked(worker->m_module.get())) ||
#endif
          overShareLocked(worker->m_module.get()) || !worker->due(now, next))
      {
        continue;
      }
      worker->m_claimed = true;
#ifdef __EMSCRIPTEN__
      worker->m_pin = runner;
#endif
      m_next = at + 1;
      return m_workers[at];
    }
    return nullptr;
  }

  // Promotes steps past their slice, then answers the runners it added to
  // keep the pool at its size, for the caller to start once unlocked.
  std::vector<Runner*> superviseLocked(
      Clock::time_point now,
      Clock::time_point& next)
  {
    if (m_resizing)
    {
      return {};
    }
    for (auto& runner : m_runners)
    {
      if (runner->slice == Slice::timing)
      {
        Clock::time_point over = runner->stepStart + kSlice;
        if (now < over)
        {
          next = std::min(next, over);
          continue;
        }
      }
      else if (runner->slice != Slice::kept)
      {
        continue;
      }
      runner->slice = promotedLocked(runner->stepping->m_module.get()) <
                              m_promotedPerVM
                          ? Slice::promoted
                          : Slice::kept;
    }
    std::vector<Runner*> started;
    for (uint32_t serving = servingLocked();
         !m_workers.empty() && serving < m_threads;
         serving++)
    {
      m_runners.push_back(std::make_unique<Runner>());
      started.push_back(m_runners.back().get());
    }
#ifdef __EMSCRIPTEN__
    // A runner each for the workers yet to take one of their own.
    uint32_t waiting = (uint32_t)std::count_if(
        m_workers.begin(),
        m_workers.end(),
        [this](const rcp<WasmWorker>& worker) {
          return worker->m_pin == nullptr &&
                 mayOwnRunnerLocked(worker->m_module.get());
        });
    uint32_t idle = (uint32_t)std::count_if(
        m_runners.begin(),
        m_runners.end(),
        [this](const auto& runner) { return !pinsLocked(runner.get()); });
    for (; idle < waiting; idle++)
    {
      m_runners.push_back(std::make_unique<Runner>());
      started.push_back(m_runners.back().get());
    }
#endif
    return started;
  }

#ifdef __EMSCRIPTEN__
  // An instance never leaves the thread it began on, so a VM's workers each
  // get a runner of their own, up to its cap, and share only past it.
  bool mayOwnRunnerLocked(const WasmLaneModule* module) const
  {
    uint32_t owned = (uint32_t)std::count_if(
        m_runners.begin(),
        m_runners.end(),
        [this, module](const auto& runner) {
          return std::any_of(
              m_workers.begin(),
              m_workers.end(),
              [&](const rcp<WasmWorker>& worker) {
                return worker->m_pin == runner.get() &&
                       worker->m_module.get() == module;
              });
        });
    return owned < lane_timing::kWebWorkerThreadsPerVM;
  }
#endif

  void start(const std::vector<Runner*>& runners)
  {
    for (Runner* runner : runners)
    {
      JobPool::makeThread([this, runner]() { runnerMain(runner); }).detach();
    }
  }

  // A VM's workers share its lane module.
  uint32_t countLocked(Slice slice, const WasmLaneModule* module) const
  {
    return (uint32_t)std::count_if(
        m_runners.begin(),
        m_runners.end(),
        [slice, module](const auto& runner) {
          return runner->slice == slice &&
                 runner->stepping->m_module.get() == module;
        });
  }

  uint32_t promotedLocked(const WasmLaneModule* module) const
  {
    return countLocked(Slice::promoted, module);
  }

  // The serving threads each VM with workers may keep with long steps, so
  // one VM's spinning workers never hold every VM's threads.
  uint32_t shareLocked() const
  {
    std::vector<const WasmLaneModule*> vms;
    for (const rcp<WasmWorker>& worker : m_workers)
    {
      if (std::find(vms.begin(), vms.end(), worker->m_module.get()) ==
          vms.end())
      {
        vms.push_back(worker->m_module.get());
      }
    }
    return vms.empty() ? m_threads : m_threads / (uint32_t)vms.size();
  }

  bool overShareLocked(const WasmLaneModule* module) const
  {
    uint32_t kept = countLocked(Slice::kept, module);
    return kept != 0 && kept >= shareLocked();
  }

  // Kept runners past their VM's share leave their slot to the others.
  uint32_t servingLocked() const
  {
    uint32_t share = shareLocked();
    uint32_t serving = 0;
    std::vector<const WasmLaneModule*> counted;
    for (const auto& runner : m_runners)
    {
      if (runner->slice == Slice::promoted)
      {
        continue;
      }
      if (runner->slice != Slice::kept)
      {
        serving++;
        continue;
      }
      const WasmLaneModule* module = runner->stepping->m_module.get();
      if (std::find(counted.begin(), counted.end(), module) == counted.end())
      {
        counted.push_back(module);
        serving += std::min(countLocked(Slice::kept, module), share);
      }
    }
    return serving;
  }

  // Answers the pool's reference, for the caller to drop unlocked.
  rcp<WasmWorker> eraseLocked(WasmWorker* worker)
  {
    auto found = std::find_if(
        m_workers.begin(),
        m_workers.end(),
        [worker](const rcp<WasmWorker>& held) { return held.get() == worker; });
    if (found == m_workers.end())
    {
      return nullptr;
    }
    rcp<WasmWorker> erased = std::move(*found);
    m_workers.erase(found);
    return erased;
  }

  bool pinsLocked(const Runner* runner) const
  {
    return std::any_of(
        m_workers.begin(),
        m_workers.end(),
        [runner](const rcp<WasmWorker>& worker) {
          return worker->m_pin == runner;
        });
  }

  std::mutex m_mutex;
  WakeWord m_wake;
  std::vector<rcp<WasmWorker>> m_workers;
  std::vector<std::unique_ptr<Runner>> m_runners;
  std::condition_variable m_runnersLeft;
  std::condition_variable m_supervise;
  // While configure waits for every runner to leave, none starts.
  bool m_resizing = false;
  bool m_supervising = false;
  // Set while no step is timed, so only a step starting then wakes it.
  bool m_superviseIdle = false;
  uint32_t m_threads;
  uint32_t m_promotedPerVM;
  size_t m_next = 0;
};
#endif

namespace
{
// What a worker's signal waits watch: nothing waits without threads.
WakeWord* watchWord()
{
#if RIVE_POOL_THREADS()
  return &WasmWorkerPool::instance().wakeWord();
#else
  return nullptr;
#endif
}
} // namespace

// --- workers -----------------------------------------------------------------

WasmWorker* WasmWorker::current() { return WasmLane::currentOf<WasmWorker>(); }

WasmWorker::WasmWorker(
    rcp<WasmLaneModule> module,
    uint32_t entry,
    std::vector<uint8_t> input)
    : WasmLane(kKind, std::move(module), entry, std::move(input))
{}

// The pool holds a threaded worker until it ends, so only one stepped at a
// poll can end here.
WasmWorker::~WasmWorker()
{
  if (m_begun && !m_ended)
  {
    end();
  }
}

void WasmWorker::stop()
{
  m_stopping.store(true);
#if RIVE_POOL_THREADS()
  if (WasmWorkerPool::instance().takeUnstarted(this))
  {
    end();
    return;
  }
  // A step already running never sees the stop; the one delivering it arms
  // its own grace.
  {
    std::lock_guard<std::mutex> lock(WasmWorkerPool::instance().mutex());
    if (m_claimed)
    {
      interruptAfter(kStopGraceMs);
    }
  }
  WasmWorkerPool::instance().wakeWord().wake();
#else
  // Only the VM's thread steps it.
  if (!m_begun && !m_ended)
  {
    end();
  }
#endif
}

void WasmWorker::finished(bool ok, const uint8_t* result, uint32_t size)
{
  // A crafted module may call again, while the VM's thread reads the
  // result.
  if (m_finished)
  {
    return;
  }
  m_finished = true;
  // On the web the page copied the result in already.
  if (ok && result != nullptr)
  {
    m_result.assign(result, result + size);
  }
  m_state.store(ok ? LaneState::done : LaneState::failed);
}

// --- waits -------------------------------------------------------------------

uint32_t WasmWorker::addWait(
    uint32_t signal,
    double after,
    double timeoutSeconds)
{
  rcp<SharedSignal> found = SignalWait::find(signal, sharedOwner());
  m_waits.emplace_back(
      m_nextWait++,
      sharedOwner(),
      signal,
      found.get(),
      after,
      timeoutSeconds);
  WakeWord* word = watchWord();
  if (found != nullptr && word != nullptr)
  {
    found->addWatcher(word);
  }
  return m_waits.back().id;
}

// A signal already gone keeps no watchers anyone could notify.
void WasmWorker::unwatch(const SignalWait& wait)
{
  WakeWord* word = watchWord();
  rcp<SharedSignal> found = SignalWait::find(wait.signal, wait.owner);
  if (found != nullptr && word != nullptr)
  {
    found->removeWatcher(word);
  }
}

void WasmWorker::dropWaits()
{
  for (const SignalWait& wait : m_waits)
  {
    unwatch(wait);
  }
  m_waits.clear();
}

// --- the lifecycle -----------------------------------------------------------

WasmWorker::Step WasmWorker::run()
{
  Step result;
  if (!m_begun)
  {
    // A worker stopped before it began never runs.
    result = !m_stopping.load() && begin() ? Step::progressed : Step::done;
  }
  else
  {
    result = step();
  }
  // The next step may run on another runner thread.
  forgetRecentRegions();
  if (result == Step::done)
  {
    // Only the stepping thread can hold what its trap left locked.
    releaseTrappedRegion();
    end();
  }
  return result;
}

bool WasmWorker::due(Clock::time_point now, Clock::time_point& earliest) const
{
  if (m_ended)
  {
    return false;
  }
  if (!m_begun || m_stopping.load())
  {
    return true;
  }
  for (const SignalWait& wait : m_waits)
  {
    double value;
    if (wait.fired(now, value))
    {
      return true;
    }
    earliest = std::min(earliest, wait.deadline);
  }
  return false;
}

bool WasmWorker::begin()
{
  m_begun = true;
  WasmLane* outerLane = WasmLane::setCurrent(this);
  bool ok = startInstance() && collect();
  if (ok && !m_finished)
  {
    m_state.store(LaneState::running);
  }
  WasmLane::setCurrent(outerLane);
  return ok && !m_finished;
}

WasmWorker::Step WasmWorker::step()
{
  // A worker that awaits again after its stop was delivered would be woken
  // with it forever; it is done.
  if (m_finished || m_stopDelivered)
  {
    return Step::done;
  }
  std::vector<std::pair<uint32_t, double>> ready;
  auto now = Clock::now();
  bool stopping = m_stopping.load();
  for (auto it = m_waits.begin(); it != m_waits.end();)
  {
    double value = kStopping;
    if (!stopping && !it->fired(now, value))
    {
      ++it;
      continue;
    }
    ready.push_back({it->id, value});
    unwatch(*it);
    it = m_waits.erase(it);
  }
  if (ready.empty())
  {
    // A stopped worker with nothing parked is stalled on a promise no
    // host wakes; it is done.
    return stopping ? Step::done : Step::idle;
  }
  if (stopping)
  {
    interruptAfter(kStopGraceMs);
  }
  WasmLane* outerLane = WasmLane::setCurrent(this);
  bool ok = true;
  for (const auto& [id, value] : ready)
  {
    m_stopDelivered = m_stopDelivered || value == kStopping;
    if (!wake(id, value))
    {
      ok = false;
      break;
    }
  }
  ok = ok && collect();
  WasmLane::setCurrent(outerLane);
  return ok && !m_finished ? Step::progressed : Step::done;
}

void WasmWorker::end()
{
  dropWaits();
  endInstance();
  // Published after the instance ends, so a stop it prompts finds none.
  if (!m_finished && m_state.load() < LaneState::done)
  {
    m_state.store(m_stopping.load() ? LaneState::stopped : LaneState::failed);
  }
  m_ended.store(true);
}

// --- the WAMR backend --------------------------------------------------------

#ifndef __EMSCRIPTEN__
namespace
{
void workerFinished(
    wasm_exec_env_t,
    uint32_t ok,
    const uint8_t* result,
    uint32_t size)
{
  if (WasmWorker* worker = WasmWorker::current())
  {
    worker->finished(ok != 0, result, size);
  }
}

uint32_t workerWait(
    wasm_exec_env_t,
    uint32_t signal,
    double after,
    double timeoutSeconds)
{
  WasmWorker* worker = WasmWorker::current();
  return worker != nullptr ? worker->addWait(signal, after, timeoutSeconds) : 0;
}

uint32_t workerStopping(wasm_exec_env_t)
{
  WasmWorker* worker = WasmWorker::current();
  return worker != nullptr && worker->stopping() ? 1 : 0;
}

NativeSymbol kWorkerNatives[] = {
    {"finished", (void*)workerFinished, "(i*~)", nullptr},
    {"wait", (void*)workerWait, "(iFF)i", nullptr},
    {"stopping", (void*)workerStopping, "()i", nullptr},
};

constexpr uint32_t kWorkerStack = 512 * 1024;
} // namespace

void rive::registerWorkerNatives()
{
  static std::once_flag once;
  std::call_once(once, []() {
    wasm_runtime_register_natives(
        "rive_worker_v1",
        kWorkerNatives,
        sizeof(kWorkerNatives) / sizeof(kWorkerNatives[0]));
  });
}

bool WasmWorker::startInstance()
{
  if (!instantiate(kWorkerStack))
  {
    return false;
  }
  if (m_stopping.load())
  {
    interruptAfter(kStopGraceMs);
  }
  m_collectFn = lookup(lane_layout::kFrameMinorExport, 0, 1, true);
  uint32_t argv[2] = {};
  if (!runStart(argv))
  {
    failTrap();
    return false;
  }
  uint32_t at = argv[0];
  if (!call(m_module->entryNames[m_entry].c_str(), 2, argv))
  {
    failTrap();
    return false;
  }
  argv[0] = at;
  if (!call(lane_layout::kLaneFreeExport, 1, argv))
  {
    failTrap();
    return false;
  }
  return true;
}

bool WasmWorker::wake(uint32_t id, double value)
{
  if (m_wakeFn == nullptr &&
      (m_wakeFn = lookup(lane_layout::kWorkerWakeExport, 3, 3)) == nullptr)
  {
    return false;
  }
  wasm_val_t args[2];
  args[0].kind = WASM_I32;
  args[0].of.i32 = (int32_t)id;
  args[1].kind = WASM_F64;
  args[1].of.f64 = value;
  if (!wasm_runtime_call_wasm_a(
          (wasm_exec_env_t)m_execEnv,
          (wasm_function_inst_t)m_wakeFn,
          0,
          nullptr,
          2,
          args))
  {
    failTrap();
    return false;
  }
  return true;
}

// Back at the host no frame is live, so the frame collector may run.
bool WasmWorker::collect()
{
  uint32_t argv[1] = {0};
  if (m_collectFn != nullptr && !call(m_collectFn, 0, argv))
  {
    failTrap();
    return false;
  }
  return true;
}

void WasmWorker::endInstance()
{
  m_wakeFn = nullptr;
  m_collectFn = nullptr;
  teardown();
}

#else
// --- the browser backend -----------------------------------------------------

// The page runner calls these back from a worker's natives, with the worker
// it bound them to.
extern "C" EMSCRIPTEN_KEEPALIVE uint32_t rive_web_worker_wait(
    uint32_t worker,
    uint32_t signal,
    double after,
    double timeout)
{
  return ((WasmWorker*)(uintptr_t)worker)->addWait(signal, after, timeout);
}

extern "C" EMSCRIPTEN_KEEPALIVE void rive_web_worker_finished(
    uint32_t worker,
    uint32_t ok)
{
  ((WasmWorker*)(uintptr_t)worker)->finished(ok != 0, nullptr, 0);
}

extern "C" EMSCRIPTEN_KEEPALIVE uint32_t
rive_web_worker_stopping(uint32_t worker)
{
  return ((WasmWorker*)(uintptr_t)worker)->stopping() ? 1 : 0;
}

// clang-format off
EM_JS_DEPS(riveWebWorkers, "$stringToNewUTF8");

// These answer null, or a malloc'd error.
EM_JS(char*, riveWebWorkerStart,
      (uint32_t worker, uint32_t lane, uint32_t moduleId,
       const uint8_t* module, uint32_t moduleSize, uint32_t entry,
       const uint8_t* input, uint32_t inputSize, void* output,
       uint32_t* idPtr), {
    let finished = false;
    const natives = {
        wait: (signal, after, timeout) =>
            _rive_web_worker_wait(worker, signal, after, timeout),
        finished: (ok, result) => {
            // The VM's thread may be reading the first result.
            if (finished) {
                return;
            }
            finished = true;
            if (ok) {
                // Resizing may grow the heap, which replaces HEAPU8.
                const at = _rive_web_job_output(output, result.length);
                HEAPU8.set(result, at);
            }
            _rive_web_worker_finished(worker, ok);
        },
        stopping: () => _rive_web_worker_stopping(worker),
    };
    const result = Module['riveScripting']['workerStart'](
        lane,
        moduleId,
        () => HEAPU8.slice(module, module + moduleSize),
        entry,
        HEAPU8.slice(input, input + inputSize),
        natives);
    if (!result.ok) {
        return stringToNewUTF8(result.error);
    }
    HEAPU32[idPtr >> 2] = result.id;
    return 0;
});

EM_JS(char*, riveWebWorkerWake, (uint32_t id, uint32_t waitId, double value), {
    const error = Module['riveScripting']['workerWake'](id, waitId, value);
    return error === null ? 0 : stringToNewUTF8(error);
});

EM_JS(char*, riveWebWorkerCollect, (uint32_t id), {
    const error = Module['riveScripting']['workerCollect'](id);
    return error === null ? 0 : stringToNewUTF8(error);
});

EM_JS(void, riveWebWorkerEnd, (uint32_t id), {
    Module['riveScripting']['workerEnd'](id);
});
// clang-format on

bool WasmWorker::startInstance()
{
  if (!riveWebAttach())
  {
    fail("no script runner on this thread");
    return false;
  }
  if (m_stopping.load())
  {
    interruptAfter(kStopGraceMs);
  }
  std::vector<uint8_t> input = takeInput();
  char* error = riveWebWorkerStart(
      (uint32_t)(uintptr_t)this,
      (uint32_t)(uintptr_t)(WasmLane*)this,
      m_module->id,
      m_module->bytes.data(),
      (uint32_t)m_module->bytes.size(),
      m_entry,
      input.data(),
      (uint32_t)input.size(),
      &m_result,
      &m_webInstance);
  if (error != nullptr)
  {
    failTaken(error);
    return false;
  }
  return true;
}

bool WasmWorker::wake(uint32_t id, double value)
{
  char* error = riveWebWorkerWake(m_webInstance, id, value);
  if (error != nullptr)
  {
    failTaken(error);
    return false;
  }
  return true;
}

bool WasmWorker::collect()
{
  char* error = riveWebWorkerCollect(m_webInstance);
  if (error != nullptr)
  {
    failTaken(error);
    return false;
  }
  return true;
}

void WasmWorker::endInstance()
{
  if (m_webInstance != 0)
  {
    riveWebWorkerEnd(m_webInstance);
    m_webInstance = 0;
  }
}

#endif

// --- the set -----------------------------------------------------------------

void WasmWorkers::configurePool(uint32_t threads, uint32_t promotedPerVM)
{
#if RIVE_POOL_THREADS()
  WasmWorkerPool::instance().configure(threads, promotedPerVM);
#else
  (void)threads;
  (void)promotedPerVM;
#endif
}

WasmWorkers::~WasmWorkers()
{
  for (auto& worker : m_lanes)
  {
    worker->stop();
  }
#if RIVE_POOL_THREADS()
  auto deadline = Clock::now() + std::chrono::milliseconds(kStopGraceMs);
  for (auto& worker : m_lanes)
  {
    WasmWorkerPool::instance().join(worker.get(), deadline);
  }
#endif
}

rcp<WasmWorker> WasmWorkers::spawn(
    uint32_t entry,
    std::vector<uint8_t> input,
    uint32_t pageThreadBudgetMs)
{
  if (entry >= entryCount())
  {
    return nullptr;
  }
  auto worker = add(make_rcp<WasmWorker>(m_module, entry, std::move(input)));
  worker->setPageThreadBudgetMs(pageThreadBudgetMs);
#if RIVE_POOL_THREADS()
  WasmWorkerPool::instance().add(worker);
#endif
  return worker;
}

void WasmWorkers::pump()
{
#if !RIVE_POOL_THREADS()
  // A worker parked on something already true is always due, so the bound
  // is time.
  auto until = Clock::now() +
               std::chrono::milliseconds(lane_timing::kCooperativeSliceMs);
  bool progressed = true;
  while (progressed && Clock::now() < until)
  {
    progressed = false;
    for (auto& worker : m_lanes)
    {
      if (worker->over())
      {
        continue;
      }
      PageThreadBudget budget(*worker);
      if (worker->run() == WasmWorker::Step::progressed)
      {
        progressed = true;
      }
    }
  }
#endif
}

bool WasmWorkers::due() const
{
  Clock::time_point now = Clock::now();
  Clock::time_point earliest = Clock::time_point::max();
#if RIVE_POOL_THREADS()
  std::lock_guard<std::mutex> lock(WasmWorkerPool::instance().mutex());
#endif
  bool due = std::any_of(
      m_lanes.begin(),
      m_lanes.end(),
      [&](const rcp<WasmWorker>& worker) {
#if RIVE_POOL_THREADS()
        if (worker->m_claimed)
        {
          return false;
        }
#endif
        return worker->due(now, earliest);
      });
#if !RIVE_POOL_THREADS()
  // Only polls step a worker here, so a timed wait keeps them coming.
  due = due || earliest != Clock::time_point::max();
#endif
  return due;
}

bool WasmWorkers::idle() const
{
  Clock::time_point now = Clock::now();
  Clock::time_point earliest = Clock::time_point::max();
#if RIVE_POOL_THREADS()
  std::lock_guard<std::mutex> lock(WasmWorkerPool::instance().mutex());
#endif
  return std::none_of(
      m_lanes.begin(),
      m_lanes.end(),
      [&](const rcp<WasmWorker>& worker) {
#if RIVE_POOL_THREADS()
        // A stop that took an unstarted worker leaves it
        // claimed.
        if (worker->m_claimed && !worker->over())
        {
          return true;
        }
#endif
        return worker->due(now, earliest);
      });
}

void WasmWorkers::parkedLines(std::vector<std::string>& lines) const
{
  Clock::time_point now = Clock::now();
  std::vector<std::pair<const WasmWorker*, std::vector<SignalWait>>> parked;
  {
#if RIVE_POOL_THREADS()
    std::lock_guard<std::mutex> lock(WasmWorkerPool::instance().mutex());
#endif
    Clock::time_point earliest = Clock::time_point::max();
    for (const auto& worker : m_lanes)
    {
#if RIVE_POOL_THREADS()
      if (worker->m_claimed)
      {
        continue;
      }
#endif
      if (!worker->over() && !worker->due(now, earliest))
      {
        parked.emplace_back(worker.get(), worker->m_waits);
      }
    }
  }
  for (const auto& [worker, waits] : parked)
  {
    std::string name = worker->name();
    if (waits.empty())
    {
      lines.push_back(
          name + " is still waiting on a promise nothing will settle");
    }
    for (const SignalWait& wait : waits)
    {
      std::string what = "sleeping";
      if (wait.signal != 0)
      {
        bool space = false;
        uint32_t ring = SharedRegistry::ringOf(wait.signal, wait.owner, space);
        if (ring == 0)
        {
          what = "waiting for signal " + std::to_string(wait.signal);
        }
        else
        {
          what = std::string("waiting for a ") +
                 (space ? "read from" : "write to") + " ring " +
                 std::to_string(ring);
        }
      }
      char seconds[32];
      snprintf(
          seconds,
          sizeof(seconds),
          "%.2f",
          std::chrono::duration<double>(now - wait.since).count());
      lines.push_back(name + " is still " + what + " after " + seconds + " s");
    }
  }
}

#endif
