#ifdef WITH_RIVE_SCRIPTING_WASM

#include "rive/wasm/module_tier_ladder.hpp"

#ifdef RIVE_WASM_TIER_LADDER

#include <algorithm>
#include <atomic>
#include <cerrno>
#include <cstdio>
#include <filesystem>
#include <fstream>
#include <iterator>
#include <fcntl.h>
#include <cstdlib>
#include <cstring>
#include <signal.h>
#include <spawn.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

extern char** environ;

namespace rive
{

ModuleTierLadder& ModuleTierLadder::instance()
{
    static ModuleTierLadder* ladder = new ModuleTierLadder();
    return *ladder;
}

ModuleTierLadder::~ModuleTierLadder()
{
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_terminating = true;
        for (Job* job : m_running)
        {
            job->cancelled = true;
#ifndef RIVE_NX
            if (job->pid > 0)
            {
                kill(job->pid, SIGKILL);
            }
#endif
        }
    }
    m_workAvailable.notify_all();
    for (auto& worker : m_workers)
    {
        worker.join();
    }
}

void ModuleTierLadder::configure(const std::string& wamrcPath,
                                 const std::string& cacheDir)
{
    std::unique_lock<std::mutex> lock(m_mutex);
    m_wamrcPath = wamrcPath;
    m_versionProbed = false;
    if (m_wamrcPath.empty())
    {
        if (const char* env = getenv("RIVE_WAMRC"))
        {
            m_wamrcPath = env;
        }
    }
    m_cacheDir = cacheDir;
}

bool ModuleTierLadder::enabled()
{
    std::unique_lock<std::mutex> lock(m_mutex);
    if (m_wamrcPath.empty() && getenv("RIVE_WAMRC") != nullptr)
    {
        m_wamrcPath = getenv("RIVE_WAMRC");
    }
    // Self-configure from env so the first module load, which happens
    // before any host configure call, can stage its pristine bytes.
    if (m_cacheDir.empty() && !m_wamrcPath.empty())
    {
        const char* dirEnv = getenv("RIVE_AOT_CACHE_DIR");
#ifdef RIVE_NX
        // No temp_directory_path in this libc++, and the platform cannot map
        // executable pages anyway, so the ladder only runs when pointed at a
        // directory explicitly.
        m_cacheDir = dirEnv != nullptr ? dirEnv : "";
#else
        m_cacheDir =
            dirEnv != nullptr
                ? dirEnv
                : (std::filesystem::temp_directory_path() / "rive_aot_cache")
                      .string();
#endif
    }
    if (m_wamrcPath.empty() || m_cacheDir.empty())
    {
        return false;
    }
    wamrcVersion();
    return m_wamrcUsable;
}

void ModuleTierLadder::onArrival(ArrivalCallback callback)
{
    std::unique_lock<std::mutex> lock(m_mutex);
    m_arrival = std::move(callback);
}

const std::string& ModuleTierLadder::wamrcVersion()
{
    // Callers hold m_mutex. The version keys the cache so a compiler swap
    // reads as misses, never as stale native code.
    if (!m_versionProbed)
    {
        m_versionProbed = true;
        m_wamrcVersion = "unknown";
#ifndef RIVE_NX
        std::string cmd = m_wamrcPath + " --version 2>/dev/null";
        if (FILE* pipe = popen(cmd.c_str(), "r"))
        {
            char line[128] = {0};
            if (fgets(line, sizeof(line), pipe) != nullptr)
            {
                std::string v(line);
                while (!v.empty() && (v.back() == '\n' || v.back() == ' '))
                {
                    v.pop_back();
                }
                for (char& c : v)
                {
                    if (c == ' ' || c == '/')
                    {
                        c = '-';
                    }
                }
                if (!v.empty())
                {
                    m_wamrcVersion = v;
                }
            }
            pclose(pipe);
        }
        // Every compile passes --rive-interrupt, which an unpatched wamrc
        // rejects; say so once rather than fail each compile quietly.
        std::string probe =
            m_wamrcPath + " --rive-interrupt --version >/dev/null 2>&1";
        m_wamrcUsable = system(probe.c_str()) == 0;
        if (!m_wamrcUsable)
        {
            fprintf(stderr,
                    "wasm aot: %s lacks --rive-interrupt; build wamrc from "
                    "our patched WAMR (runtime/scripting/wamr_patches). AOT "
                    "is off.\n",
                    m_wamrcPath.c_str());
        }
#endif
    }
    return m_wamrcVersion;
}

// The module exports __riveHostBudget. A byte search suffices: a false
// hit only adds interrupt checks.
static bool asksHostBudget(const std::string& wasmPath)
{
    std::ifstream in(wasmPath, std::ios::binary);
    std::string bytes((std::istreambuf_iterator<char>(in)),
                      std::istreambuf_iterator<char>());
    return bytes.find("__riveHostBudget") != std::string::npos;
}

std::string ModuleTierLadder::keyedCacheDir()
{
    // The revision folds our wamrc flag choices into the cache key; bump
    // it whenever species flags change or stale artifacts get served on a
    // cache hit.
    std::string dir = m_cacheDir + "/" + wamrcVersion() + "-r8";
    mkdir(m_cacheDir.c_str(), 0755);
    mkdir(dir.c_str(), 0755);
    return dir;
}

std::string ModuleTierLadder::artifactName(uint64_t moduleKey,
                                           TierSpecies species)
{
    const char* pattern = "%016llx.aot";
    if (species == TierSpecies::o0)
    {
        pattern = "%016llx.o0.aot";
    }
    else if (species == TierSpecies::hw)
    {
        pattern = "%016llx.hw.aot";
    }
    char name[64];
    snprintf(name, sizeof(name), pattern, (unsigned long long)moduleKey);
    return name;
}

std::string ModuleTierLadder::artifactPath(uint64_t moduleKey,
                                           TierSpecies species)
{
    std::unique_lock<std::mutex> lock(m_mutex);
    if (m_wamrcPath.empty() || m_cacheDir.empty())
    {
        return std::string();
    }
    std::string path = keyedCacheDir() + "/" + artifactName(moduleKey, species);
    struct stat st;
    if (stat(path.c_str(), &st) == 0)
    {
        return path;
    }
    return std::string();
}

// The cache is shared across processes and a name must never be visible
// half-written: write a process-unique temp, then atomically rename.
static bool writeFileAtomic(const std::string& path, Span<const uint8_t> bytes)
{
    std::string tmpPath = path + "." + std::to_string(getpid()) + ".tmp";
    FILE* f = fopen(tmpPath.c_str(), "wb");
    if (f == nullptr)
    {
        return false;
    }
    size_t written = fwrite(bytes.data(), 1, bytes.size(), f);
    if (fclose(f) != 0 || written != bytes.size())
    {
        unlink(tmpPath.c_str());
        return false;
    }
    if (rename(tmpPath.c_str(), path.c_str()) != 0)
    {
        unlink(tmpPath.c_str());
        return false;
    }
    return true;
}

void ModuleTierLadder::stagePristine(uint64_t moduleKey,
                                     Span<const uint8_t> moduleBytes)
{
    if (!enabled())
    {
        return;
    }
    std::unique_lock<std::mutex> lock(m_mutex);
    char wasmName[64];
    snprintf(wasmName,
             sizeof(wasmName),
             "%016llx.wasm",
             (unsigned long long)moduleKey);
    std::string wasmPath = keyedCacheDir() + "/" + wasmName;
    struct stat st;
    if (stat(wasmPath.c_str(), &st) == 0)
    {
        return;
    }
    writeFileAtomic(wasmPath, moduleBytes);
}

std::string ModuleTierLadder::compileSync(uint64_t moduleKey,
                                          Span<const uint8_t> moduleBytes,
                                          TierSpecies species)
{
    if (!enabled())
    {
        return std::string();
    }
    std::string existing = artifactPath(moduleKey, species);
    if (!existing.empty())
    {
        return existing;
    }
    stagePristine(moduleKey, moduleBytes);
    std::string wasmPath;
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        char wasmName[64];
        snprintf(wasmName,
                 sizeof(wasmName),
                 "%016llx.wasm",
                 (unsigned long long)moduleKey);
        wasmPath = keyedCacheDir() + "/" + wasmName;
    }
    // Runs on the caller's thread and never joins m_running, so lane
    // supersession cannot kill it out from under the boot.
    Job job{std::string(), moduleKey, species, wasmPath, 0};
    if (!runWamrc(job))
    {
        return std::string();
    }
    return artifactPath(moduleKey, species);
}

void ModuleTierLadder::schedule(const std::string& laneId,
                                uint64_t moduleKey,
                                Span<const uint8_t> moduleBytes)
{
    if (!enabled())
    {
        return;
    }
    std::unique_lock<std::mutex> lock(m_mutex);
    uint64_t generation = m_nextGeneration++;
    m_laneGeneration[laneId] = generation;
    // Supersede the lane: queued stale jobs get skipped by the generation
    // check; running ones die now so the pool frees up for the new hash.
    // Same-hash jobs are not stale — a rebuild of identical bytes must not
    // kill its own compile — so they ride forward on the new generation
    // and their species skip re-queueing below.
    std::vector<TierSpecies> inFlight;
    for (Job* job : m_running)
    {
        if (job->laneId != laneId || job->generation >= generation)
        {
            continue;
        }
        // A job already cancelled by an earlier supersede will not produce
        // an artifact, so it cannot stand in for this request even when the
        // bytes match: let its species re-queue below.
        if (job->moduleKey == moduleKey && !job->cancelled)
        {
            job->generation = generation;
            inFlight.push_back(job->species);
        }
        else if (job->moduleKey != moduleKey && job->pid > 0 && !job->cancelled)
        {
            job->cancelled = true;
#ifndef RIVE_NX
            kill(job->pid, SIGKILL);
#endif
        }
    }
    for (Job& job : m_queue)
    {
        if (job.laneId == laneId && job.moduleKey == moduleKey &&
            !job.cancelled)
        {
            job.generation = generation;
            inFlight.push_back(job.species);
        }
    }

    std::string dir = keyedCacheDir();
    char wasmName[64];
    snprintf(wasmName,
             sizeof(wasmName),
             "%016llx.wasm",
             (unsigned long long)moduleKey);
    std::string wasmPath = dir + "/" + wasmName;

    // On guard-page builds the top rung is the hw species: no inline
    // bounds checks and growth never moves the memory base.
#ifdef RIVE_WASM_HW_BOUNDS
    constexpr TierSpecies kTopSpecies = TierSpecies::hw;
#else
    constexpr TierSpecies kTopSpecies = TierSpecies::o3;
#endif
    std::vector<TierSpecies> wanted;
    if (moduleBytes.size() <= kStraightToO3Bytes)
    {
        wanted = {kTopSpecies};
    }
    else
    {
        wanted = {TierSpecies::o0, kTopSpecies};
    }

    bool queued = false;
    for (TierSpecies species : wanted)
    {
        if (std::find(inFlight.begin(), inFlight.end(), species) !=
            inFlight.end())
        {
            continue;
        }
        std::string artifact = dir + "/" + artifactName(moduleKey, species);
        struct stat st;
        if (stat(artifact.c_str(), &st) == 0)
        {
            if (m_arrival)
            {
                Artifact ready{moduleKey, species, artifact};
                lock.unlock();
                m_arrival(ready);
                lock.lock();
            }
            continue;
        }
        if (!queued)
        {
            // A pristine stage from before the in-place load wins; the bytes
            // passed here may already be loader-rewritten.
            struct stat wasmStat;
            if (stat(wasmPath.c_str(), &wasmStat) != 0 &&
                !writeFileAtomic(wasmPath, moduleBytes))
            {
                return;
            }
            queued = true;
        }
        m_queue.push_back(
            Job{laneId, moduleKey, species, wasmPath, generation});
    }
    if (queued)
    {
        ensureWorkers();
        m_workAvailable.notify_all();
    }
}

void ModuleTierLadder::ensureWorkers()
{
    if (!m_workers.empty())
    {
        return;
    }
    for (unsigned i = 0; i < kWorkerCount; i++)
    {
        m_workers.emplace_back([this] { workerLoop(); });
    }
}

void ModuleTierLadder::workerLoop()
{
    std::unique_lock<std::mutex> lock(m_mutex);
    for (;;)
    {
        m_workAvailable.wait(lock, [this] {
            return m_terminating || !m_queue.empty();
        });
        if (m_terminating)
        {
            return;
        }
        Job job = m_queue.front();
        m_queue.pop_front();
        auto lane = m_laneGeneration.find(job.laneId);
        if (lane != m_laneGeneration.end() && job.generation < lane->second)
        {
            continue;
        }
        m_running.push_back(&job);
        lock.unlock();
        bool ok = runWamrc(job);
        lock.lock();
        m_running.erase(std::find(m_running.begin(), m_running.end(), &job));
        if (ok && !job.cancelled && m_arrival)
        {
            Artifact ready{job.moduleKey,
                           job.species,
                           keyedCacheDir() + "/" +
                               artifactName(job.moduleKey, job.species)};
            lock.unlock();
            m_arrival(ready);
            lock.lock();
        }
        if (m_queue.empty() && m_running.empty())
        {
            m_idle.notify_all();
        }
    }
}

bool ModuleTierLadder::runWamrc(Job& job)
{
    // Callers dropped m_mutex; only job fields and immutable config are
    // touched off-lock, except pid which the scheduler reads under lock to
    // kill superseded compiles.
    std::string finalPath;
    std::string wamrc;
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        finalPath =
            keyedCacheDir() + "/" + artifactName(job.moduleKey, job.species);
        wamrc = m_wamrcPath;
    }
    // Unique temp per compile: the same artifact can be raced by a worker
    // and a sync boot, or by two processes sharing the cache.
    static std::atomic<uint64_t> tmpSerial{0};
    std::string tmpPath = finalPath + "." + std::to_string(getpid()) + "-" +
                          std::to_string(++tmpSerial) + ".tmp";

    std::vector<std::string> args = {wamrc};
    if (job.species == TierSpecies::hw)
    {
        // Guard-page bounds; native stack checks stay sw (the runtime
        // builds with WASM_DISABLE_STACK_HW_BOUND_CHECK).
        args.push_back("--bounds-checks=0");
        args.push_back("--stack-bounds-checks=1");
    }
    else
    {
        // sw bounds run on every build; wamrc's default hw-bounds output
        // segfaults on runtimes without the guard-page trap handler.
        args.push_back("--bounds-checks=1");
    }
    if (job.species == TierSpecies::o0 || job.species == TierSpecies::hw)
    {
        args.push_back("--opt-level=0");
    }
    else
    {
        args.push_back("--opt-level=3");
    }
#if (defined(__APPLE__) || defined(_WIN32)) &&                                 \
    (defined(__aarch64__) || defined(_M_ARM64))
    // The platform clobbers x18; reserve it here so safety does not depend on
    // the wamrc we were handed. Features need an explicit cpu.
    args.push_back("--cpu=generic");
    args.push_back("--cpu-features=+reserve-x18");
#endif
    // Loop back-edges and calls check the watchdog only in modules that ask
    // for it; the module bytes, and so its cache key, decide.
    if (asksHostBudget(job.wasmPath))
    {
        args.push_back("--rive-interrupt");
    }
    args.push_back("-o");
    args.push_back(tmpPath);
    args.push_back(job.wasmPath);
    std::vector<char*> argv;
    for (auto& a : args)
    {
        argv.push_back(const_cast<char*>(a.c_str()));
    }
    argv.push_back(nullptr);

#if defined(RIVE_ANDROID) || defined(RIVE_NX)
    // No wamrc on device, and neither platform has posix_spawn; the ladder
    // never schedules compiles here.
    return false;
#else
    pid_t pid = -1;
    posix_spawn_file_actions_t actions;
    posix_spawn_file_actions_init(&actions);
    // A compiler's stdout is noise at editor runtime; stderr stays for
    // diagnosing failed compiles.
    posix_spawn_file_actions_addopen(&actions,
                                     STDOUT_FILENO,
                                     "/dev/null",
                                     O_WRONLY,
                                     0);
    int rc = posix_spawn(&pid,
                         wamrc.c_str(),
                         &actions,
                         nullptr,
                         argv.data(),
                         environ);
    posix_spawn_file_actions_destroy(&actions);
    if (rc != 0)
    {
        return false;
    }
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        job.pid = pid;
    }
    // The whole child runs below interactive priority; the editor's frame
    // loop must never contend with LLVM.
    setpriority(PRIO_PROCESS, pid, 10);

    int status = 0;
    while (waitpid(pid, &status, 0) < 0 && errno == EINTR)
    {
    }
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        job.pid = -1;
    }
    if (job.cancelled || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
    {
        if (!job.cancelled)
        {
            // wamrc prints usage errors to stdout, which is discarded; an
            // unlogged exit here is otherwise a silently dead lane.
            fprintf(stderr,
                    "[wasm] wamrc failed (exit %d) on %s\n",
                    WIFEXITED(status) ? WEXITSTATUS(status) : -1,
                    job.wasmPath.c_str());
        }
        unlink(tmpPath.c_str());
        return false;
    }
    // Atomic arrival: a partial artifact can never carry the final name.
    return rename(tmpPath.c_str(), finalPath.c_str()) == 0;
#endif
}

void ModuleTierLadder::drain()
{
    std::unique_lock<std::mutex> lock(m_mutex);
    m_idle.wait(lock, [this] { return m_queue.empty() && m_running.empty(); });
}

} // namespace rive

#endif // RIVE_WASM_TIER_LADDER
#endif // WITH_RIVE_SCRIPTING_WASM
