#ifdef WITH_RIVE_SCRIPTING_WASM

#include "rive/wasm/module_tier_ladder.hpp"
#include "rive/wasm/aot_artifact.hpp"
#include "rive/wasm/wasm_lane.hpp"

#include <cstdlib>
#include <cstring>

namespace rive
{
TierSpecies bootTierSpecies()
{
  const char* tier = getenv("RIVE_WASM_AOT_SYNC");
  if (tier != nullptr && strcmp(tier, "o0") == 0)
  {
    return TierSpecies::o0;
  }
#ifdef RIVE_WASM_HW_BOUNDS
  return TierSpecies::hw;
#else
  return TierSpecies::o3;
#endif
}

int x86_64Level(
    uint32_t leaf1Ecx,
    uint32_t leaf7Ebx,
    uint32_t extEcx,
    uint64_t xcr0)
{
  // FMA, MOVBE, XSAVE, OSXSAVE, AVX and F16C, then BMI1, AVX2 and BMI2, then
  // LZCNT, then the XMM and YMM state.
  constexpr uint32_t kLeaf1 = (1u << 12) | (1u << 22) | (1u << 26) |
                              (1u << 27) | (1u << 28) | (1u << 29);
  constexpr uint32_t kLeaf7 = (1u << 3) | (1u << 5) | (1u << 8);
  constexpr uint32_t kExt = 1u << 5;
  constexpr uint64_t kXcr0 = 0x6;
  return (leaf1Ecx & kLeaf1) == kLeaf1 && (leaf7Ebx & kLeaf7) == kLeaf7 &&
                 (extEcx & kExt) == kExt && (xcr0 & kXcr0) == kXcr0
             ? 3
             : 2;
}
} // namespace rive

#ifdef RIVE_WASM_TIER_LADDER

#include "wasm_export.h"

#include <algorithm>
#include <atomic>
#include <cerrno>
#include <chrono>
#include <cstdio>
#include <filesystem>
#include <fstream>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <thread>
#include <sys/stat.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <fcntl.h>
#include <signal.h>
#include <spawn.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <unistd.h>
#if !defined(RIVE_ANDROID) && !defined(RIVE_NX)
#include <dlfcn.h>
#endif
#if defined(__linux__) && !defined(__ANDROID__)
#include <link.h>
#endif

extern char** environ;
#endif
#if defined(__x86_64__) || defined(_M_X64)
#if defined(_MSC_VER) && !defined(__clang__)
#include <intrin.h>
#else
#include <cpuid.h>
#endif
#endif

namespace rive
{

constexpr const char* kCancelledReason = "the compile was cancelled";

static uint64_t processId()
{
#ifdef _WIN32
  return GetCurrentProcessId();
#else
  return (uint64_t)getpid();
#endif
}

static void makeDir(const std::string& path)
{
#ifdef RIVE_NX
  // Our NX libc++ has no std::filesystem directory ops.
  mkdir(path.c_str(), 0755);
#elif defined(_WIN32)
  std::error_code ec;
  std::filesystem::create_directories(path, ec);
#else
  // Private from the start, so no other user can plant artifacts.
  if (mkdir(path.c_str(), 0700) != 0 && errno == ENOENT)
  {
    size_t slash = path.find_last_of('/');
    if (slash != std::string::npos && slash != 0)
    {
      makeDir(path.substr(0, slash));
      mkdir(path.c_str(), 0700);
    }
  }
#endif
}

static bool fileExists(const std::string& path)
{
  struct stat st;
  return stat(path.c_str(), &st) == 0;
}

// Artifacts run as native code, so a cache another user can write is never
// read. One that does not exist yet gets created private.
static bool trustedCacheDir(const std::string& path)
{
#if defined(_WIN32) || defined(RIVE_NX)
  return true;
#else
  struct stat st;
  return stat(path.c_str(), &st) != 0 ||
         (S_ISDIR(st.st_mode) && st.st_uid == geteuid() &&
          (st.st_mode & (S_IWGRP | S_IWOTH)) == 0);
#endif
}

#ifndef RIVE_NX
// The temp dir is per user on Apple and Windows but shared on Linux, where
// the user's own cache dir holds the artifacts instead.
static std::string defaultCacheDir()
{
#if defined(_WIN32) || defined(__APPLE__)
  return (std::filesystem::temp_directory_path() / "rive_aot_cache").string();
#else
  const char* xdg = getenv("XDG_CACHE_HOME");
  if (xdg != nullptr && xdg[0] == '/')
  {
    return std::string(xdg) + "/rive/aot_cache";
  }
  const char* home = getenv("HOME");
  return home != nullptr && home[0] == '/'
             ? std::string(home) + "/.cache/rive/aot_cache"
             : std::string();
#endif
}
#endif

// Windows refuses to rename over an existing file, and another compile of
// the same artifact landing first is still a success.
static bool publishFile(const std::string& tmpPath, const std::string& path)
{
  if (rename(tmpPath.c_str(), path.c_str()) == 0)
  {
    return true;
  }
  std::remove(tmpPath.c_str());
  return fileExists(path);
}

// The x86-64 level this machine's host artifacts compile for, 0 off x86.
static int hostX86_64Level()
{
#if defined(__x86_64__) || defined(_M_X64)
  static const int level = [] {
    // CI holds a v3 host at the baseline, where relaxed madd calls fmaf.
    const char* cap = getenv("RIVE_AOT_X86_LEVEL");
    if (cap != nullptr && strcmp(cap, "2") == 0)
    {
      return 2;
    }
    uint32_t leaf1Ecx = 0;
    uint32_t leaf7Ebx = 0;
    uint32_t extEcx = 0;
    uint64_t xcr0 = 0;
#if defined(_MSC_VER) && !defined(__clang__)
    int regs[4];
    __cpuid(regs, 0);
    int maxLeaf = regs[0];
    __cpuid(regs, 1);
    leaf1Ecx = (uint32_t)regs[2];
    if (maxLeaf >= 7)
    {
      __cpuidex(regs, 7, 0);
      leaf7Ebx = (uint32_t)regs[1];
    }
    __cpuid(regs, 0x80000000);
    if ((uint32_t)regs[0] >= 0x80000001)
    {
      __cpuid(regs, 0x80000001);
      extEcx = (uint32_t)regs[2];
    }
    if ((leaf1Ecx & (1u << 27)) != 0)
    {
      xcr0 = _xgetbv(0);
    }
#else
    unsigned a, b, c, d;
    if (__get_cpuid(1, &a, &b, &c, &d))
    {
      leaf1Ecx = c;
    }
    if (__get_cpuid_count(7, 0, &a, &b, &c, &d))
    {
      leaf7Ebx = b;
    }
    if (__get_cpuid(0x80000001, &a, &b, &c, &d))
    {
      extEcx = c;
    }
    // xgetbv faults unless the OS turned on xsave.
    if ((leaf1Ecx & (1u << 27)) != 0)
    {
      uint32_t lo;
      uint32_t hi;
      __asm__ volatile("xgetbv" : "=a"(lo), "=d"(hi) : "c"(0));
      xcr0 = ((uint64_t)hi << 32) | lo;
    }
#endif
    return x86_64Level(leaf1Ecx, leaf7Ebx, extEcx, xcr0);
  }();
  return level;
#else
  return 0;
#endif
}

std::string wamrcHwGuardFlag()
{
  return "--rive-hw-guard=" + std::to_string(WASM_RIVE_HW_GUARD_SIZE);
}

std::string loaderBinaryPath()
{
  std::string path;
#if defined(_WIN32)
  HMODULE module = nullptr;
  char name[MAX_PATH];
  if (GetModuleHandleExA(
          GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
              GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
          (LPCSTR)&loaderBinaryPath,
          &module))
  {
    DWORD length = GetModuleFileNameA(module, name, MAX_PATH);
    if (length > 0 && length < MAX_PATH)
    {
      path.assign(name, length);
    }
  }
#elif defined(__linux__) && !defined(__ANDROID__)
  Dl_info info;
  link_map* map = nullptr;
  if (dladdr1(
          (const void*)&loaderBinaryPath,
          &info,
          (void**)&map,
          RTLD_DL_LINKMAP) != 0 &&
      map != nullptr)
  {
    // glibc names the main program by argv[0], bare on a PATH launch.
    path = map->l_name[0] == '\0' ? "/proc/self/exe" : map->l_name;
  }
#elif !defined(RIVE_ANDROID) && !defined(RIVE_NX)
  Dl_info info;
  if (dladdr((const void*)&loaderBinaryPath, &info) != 0 &&
      info.dli_fname != nullptr)
  {
    path = info.dli_fname;
  }
#endif
  return path;
}

// Every relink rewrites the binary holding the loader, so its stat tells
// builds apart without reading it.
static const std::string& loaderBuild()
{
  static const std::string build = [] {
    std::string path = loaderBinaryPath();
    struct stat st;
    uint64_t key = 0;
    if (!path.empty() && stat(path.c_str(), &st) == 0)
    {
      const uint64_t fields[] = {
          (uint64_t)st.st_ino,
          (uint64_t)st.st_size,
          (uint64_t)st.st_mtime};
      key = wasmModuleKey(
          Span<const uint8_t>((const uint8_t*)fields, sizeof(fields)));
    }
    char text[17];
    snprintf(text, sizeof(text), "%016llx", (unsigned long long)key);
    return std::string(text);
  }();
  return build;
}

// A loader fix changes no compiler key, so each build keeps its own marker.
static std::string rejectedMarker(const std::string& artifactPath)
{
  return artifactPath + "." + loaderBuild() + ".rejected";
}

#ifdef _WIN32
// CreateProcess takes one command line; quote each argument so the child's
// CRT splits it back into the same argv.
static std::string quoteArg(const std::string& arg)
{
  if (!arg.empty() && arg.find_first_of(" \t\"") == std::string::npos)
  {
    return arg;
  }
  std::string out = "\"";
  size_t slashes = 0;
  for (char c : arg)
  {
    if (c == '\\')
    {
      slashes++;
      continue;
    }
    out.append(c == '"' ? slashes * 2 + 1 : slashes, '\\');
    slashes = 0;
    out += c;
  }
  out.append(slashes * 2, '\\');
  return out + "\"";
}

static HANDLE inheritable(HANDLE handle)
{
  HANDLE copy = nullptr;
  if (handle == nullptr || handle == INVALID_HANDLE_VALUE ||
      !DuplicateHandle(
          GetCurrentProcess(),
          handle,
          GetCurrentProcess(),
          &copy,
          0,
          TRUE,
          DUPLICATE_SAME_ACCESS))
  {
    return nullptr;
  }
  return copy;
}

// Starts args below interactive priority with no console window. stdout goes
// to out, or nowhere; stderr is the host's unless quiet. Only these handles
// are inherited, so a concurrent child never holds another's pipe open.
static intptr_t startChild(
    const std::vector<std::string>& args,
    std::string* failure,
    HANDLE out = nullptr,
    bool quiet = false)
{
  std::string line;
  for (const std::string& arg : args)
  {
    line += (line.empty() ? "" : " ") + quoteArg(arg);
  }
  SECURITY_ATTRIBUTES sa{sizeof(sa), nullptr, TRUE};
  HANDLE nul = CreateFileA(
      "NUL",
      GENERIC_READ | GENERIC_WRITE,
      FILE_SHARE_READ | FILE_SHARE_WRITE,
      &sa,
      OPEN_EXISTING,
      0,
      nullptr);
  HANDLE err = quiet ? nullptr : inheritable(GetStdHandle(STD_ERROR_HANDLE));
  STARTUPINFOEXA si{};
  si.StartupInfo.cb = sizeof(si);
  si.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
  si.StartupInfo.hStdInput = nul;
  si.StartupInfo.hStdOutput = out != nullptr ? out : nul;
  si.StartupInfo.hStdError = err != nullptr ? err : nul;
  HANDLE handles[3] = {
      nul,
      si.StartupInfo.hStdOutput,
      si.StartupInfo.hStdError};
  std::sort(std::begin(handles), std::end(handles));
  DWORD handleCount = (DWORD)(std::unique(
                                  std::begin(handles),
                                  std::end(handles)) -
                              handles);
  SIZE_T attrSize = 0;
  InitializeProcThreadAttributeList(nullptr, 1, 0, &attrSize);
  std::vector<uint8_t> attrs(attrSize);
  si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)attrs.data();
  PROCESS_INFORMATION pi{};
  bool listReady = InitializeProcThreadAttributeList(
      si.lpAttributeList,
      1,
      0,
      &attrSize);
  bool ok = listReady &&
            UpdateProcThreadAttribute(
                si.lpAttributeList,
                0,
                PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
                handles,
                handleCount * sizeof(HANDLE),
                nullptr,
                nullptr) &&
            CreateProcessA(
                nullptr,
                line.data(),
                nullptr,
                nullptr,
                TRUE,
                CREATE_NO_WINDOW | BELOW_NORMAL_PRIORITY_CLASS |
                    EXTENDED_STARTUPINFO_PRESENT,
                nullptr,
                nullptr,
                &si.StartupInfo,
                &pi);
  DWORD error = ok ? 0 : GetLastError();
  if (listReady)
  {
    DeleteProcThreadAttributeList(si.lpAttributeList);
  }
  CloseHandle(nul);
  if (err != nullptr)
  {
    CloseHandle(err);
  }
  if (!ok)
  {
    *failure = "could not run " + args[0] + ", windows error " +
               std::to_string(error);
    return -1;
  }
  CloseHandle(pi.hThread);
  return (intptr_t)pi.hProcess;
}

static void killChild(intptr_t child) { TerminateProcess((HANDLE)child, 1); }

// The exit code, or -1 when the child did not exit on its own.
static int waitChild(intptr_t child)
{
  DWORD code = 1;
  if (WaitForSingleObject((HANDLE)child, INFINITE) != WAIT_OBJECT_0 ||
      !GetExitCodeProcess((HANDLE)child, &code))
  {
    return -1;
  }
  return (int)code;
}

static void releaseChild(intptr_t child) { CloseHandle((HANDLE)child); }

// Runs wamrc with flag and --version: true when it exits cleanly, with the
// first line of its output when asked.
static bool probeWamrc(
    const std::string& wamrc,
    const char* flag,
    std::string* firstLine)
{
  std::vector<std::string> args = {wamrc};
  if (flag != nullptr)
  {
    args.push_back(flag);
  }
  args.push_back("--version");
  SECURITY_ATTRIBUTES sa{sizeof(sa), nullptr, TRUE};
  HANDLE readEnd = nullptr;
  HANDLE writeEnd = nullptr;
  if (!CreatePipe(&readEnd, &writeEnd, &sa, 0))
  {
    return false;
  }
  SetHandleInformation(readEnd, HANDLE_FLAG_INHERIT, 0);
  std::string failure;
  intptr_t child = startChild(args, &failure, writeEnd, true);
  CloseHandle(writeEnd);
  std::string text;
  char buffer[256];
  DWORD read = 0;
  while (ReadFile(readEnd, buffer, sizeof(buffer), &read, nullptr) && read > 0)
  {
    text.append(buffer, read);
  }
  CloseHandle(readEnd);
  if (child == -1)
  {
    return false;
  }
  int code = waitChild(child);
  releaseChild(child);
  if (firstLine != nullptr)
  {
    *firstLine = text.substr(0, text.find('\n'));
  }
  return code == 0;
}
#elif defined(RIVE_ANDROID) || defined(RIVE_NX)
// No wamrc on device, and neither platform can spawn one.
static intptr_t startChild(
    const std::vector<std::string>&,
    std::string* failure)
{
  *failure = "wamrc cannot run on this platform";
  return -1;
}

static void killChild(intptr_t) {}

static int waitChild(intptr_t) { return -1; }

static void releaseChild(intptr_t) {}
#else
// Starts args below interactive priority; a compiler's stdout is noise at
// editor runtime, stderr stays for diagnosing failed compiles.
static intptr_t startChild(
    const std::vector<std::string>& args,
    std::string* failure)
{
  std::vector<char*> argv;
  for (const std::string& arg : args)
  {
    argv.push_back(const_cast<char*>(arg.c_str()));
  }
  argv.push_back(nullptr);
  pid_t pid = -1;
  posix_spawn_file_actions_t actions;
  posix_spawn_file_actions_init(&actions);
  posix_spawn_file_actions_addopen(
      &actions,
      STDOUT_FILENO,
      "/dev/null",
      O_WRONLY,
      0);
  int rc = posix_spawn(&pid, argv[0], &actions, nullptr, argv.data(), environ);
  posix_spawn_file_actions_destroy(&actions);
  if (rc != 0)
  {
    *failure = "could not run " + args[0] + ", " + strerror(rc);
    return -1;
  }
  // The editor's frame loop must never contend with LLVM.
  setpriority(PRIO_PROCESS, pid, 10);
  return pid;
}

static void killChild(intptr_t child) { kill((pid_t)child, SIGKILL); }

// The exit code, or -1 when the child did not exit on its own.
static int waitChild(intptr_t child)
{
  int status = 0;
  while (waitpid((pid_t)child, &status, 0) < 0 && errno == EINTR)
  {
  }
  return WIFEXITED(status) ? WEXITSTATUS(status) : -1;
}

static void releaseChild(intptr_t) {}
#endif

#if !defined(_WIN32) && !defined(RIVE_NX)
// Installed apps put wamrc under paths with spaces.
static std::string shellQuote(const std::string& text)
{
  std::string quoted = "'";
  for (char c : text)
  {
    quoted += c == '\'' ? std::string("'\\''") : std::string(1, c);
  }
  return quoted + "'";
}

// Runs wamrc with flag and --version: true when it exits cleanly, with the
// first line of its output when asked.
static bool probeWamrc(
    const std::string& wamrc,
    const char* flag,
    std::string* firstLine)
{
  std::string cmd = shellQuote(wamrc) +
                    (flag != nullptr ? " " + std::string(flag) : "") +
                    " --version" +
                    (firstLine != nullptr ? " 2>/dev/null"
                                          : " >/dev/null 2>&1");
  FILE* pipe = popen(cmd.c_str(), "r");
  if (pipe == nullptr)
  {
    return false;
  }
  char line[128] = {0};
  if (firstLine != nullptr && fgets(line, sizeof(line), pipe) != nullptr)
  {
    *firstLine = line;
  }
  return pclose(pipe) == 0;
}
#endif

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

void ModuleTierLadder::configure(
    const std::string& wamrcPath,
    const std::string& cacheDir,
    bool compileOnBoot)
{
  // Before a rebuild can replace the loader's binary on disk.
  loaderBuild();
  std::unique_lock<std::mutex> lock(m_mutex);
  m_wamrcPath = wamrcPath;
  m_compileOnBoot = compileOnBoot;
  m_versionProbed = false;
  if (m_wamrcPath.empty())
  {
    if (const char* env = getenv("RIVE_WAMRC"))
    {
      m_wamrcPath = env;
    }
  }
  m_cacheDir = cacheDir;
  m_failures.clear();
  m_compiled.clear();
  m_pruned = false;
  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 : defaultCacheDir();
#endif
  }
}

void ModuleTierLadder::unconfigure()
{
  std::unique_lock<std::mutex> lock(m_mutex);
  m_wamrcPath.clear();
  m_cacheDir.clear();
  m_failures.clear();
  m_compiled.clear();
  m_versionProbed = false;
  m_compileOnBoot = false;
}

bool ModuleTierLadder::enabled()
{
  std::unique_lock<std::mutex> lock(m_mutex);
  return enabledLocked();
}

bool ModuleTierLadder::enabledLocked()
{
  if (m_wamrcPath.empty())
  {
    m_disabledReason =
        "no wamrc, set RIVE_WAMRC or pass --aot with our wamrc on PATH";
    return false;
  }
  if (m_cacheDir.empty())
  {
    m_disabledReason = "no aot cache, set RIVE_AOT_CACHE_DIR";
    return false;
  }
  if (!trustedCacheDir(m_cacheDir))
  {
    m_disabledReason = "the aot cache " + m_cacheDir +
                       " is not private to this user, run chmod go-w on it";
    return false;
  }
  wamrcVersion();
  m_disabledReason = m_wamrcUsable ? "" : m_wamrcPath + " " + m_wamrcProblem;
  return m_wamrcUsable;
}

std::string ModuleTierLadder::disabledReason()
{
  if (enabled())
  {
    return std::string();
  }
  std::unique_lock<std::mutex> lock(m_mutex);
  return m_disabledReason;
}

std::string ModuleTierLadder::untrustedCacheDir()
{
  std::unique_lock<std::mutex> lock(m_mutex);
  return m_cacheDir.empty() || trustedCacheDir(m_cacheDir) ? std::string()
                                                           : m_cacheDir;
}

std::string ModuleTierLadder::compilerPath()
{
  std::unique_lock<std::mutex> lock(m_mutex);
  return m_wamrcPath;
}

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 v;
    probeWamrc(m_wamrcPath, nullptr, &v);
    while (!v.empty() &&
           (v.back() == '\n' || v.back() == '\r' || v.back() == ' '))
    {
      v.pop_back();
    }
    for (char& c : v)
    {
      if (c == ' ' || c == '/')
      {
        c = '-';
      }
    }
    if (!v.empty())
    {
      m_wamrcVersion = v;
    }
    // Every build of our patched wamrc prints the same version.
    uint64_t binaryKey = 0;
    fileContentKey(m_wamrcPath, binaryKey);
    char binary[20];
    snprintf(binary, sizeof(binary), "-%016llx", (unsigned long long)binaryKey);
    m_wamrcVersion += binary;
    auto accepts = [&](const char* flag) {
      return probeWamrc(m_wamrcPath, flag, nullptr);
    };
    // Only our patched wamrc takes --rive-interrupt, and only a current one
    // the guard flag; say so once rather than fail each compile quietly.
    m_wamrcProblem.clear();
    if (!accepts("--rive-interrupt"))
    {
      m_wamrcProblem = "is not our patched wamrc; build wamrc from our WAMR "
                       "patches (runtime/scripting/wamr_patches)";
    }
    else if (!accepts(wamrcHwGuardFlag().c_str()))
    {
      m_wamrcProblem = "predates our current WAMR patches; rebuild wamrc "
                       "from the current patches "
                       "(runtime/scripting/wamr_patches)";
    }
    m_wamrcUsable = m_wamrcProblem.empty();
    m_wamrcTunes = accepts("--tune-cpu=generic");
    if (!m_wamrcUsable)
    {
      fprintf(
          stderr,
          "wasm aot: %s %s. AOT is off.\n",
          m_wamrcPath.c_str(),
          m_wamrcProblem.c_str());
    }
#endif
  }
  return m_wamrcVersion;
}

// wamrc flags naming a device target, null for one we cannot compile for.
static const char* const* crossTargetArgs(const std::string& target)
{
  // Android reserves x18 for its shadow call stack.
  static const char* const androidAarch64[] = {
      "--target=aarch64v8",
      "--target-abi=gnu",
      "--cpu=generic",
      "--cpu-features=+reserve-x18",
      nullptr};
  // wamrc compiles SIMD only for SSE4.1, which the NDK x86_64 ABI
  // guarantees.
  static const char* const androidX64[] =
      {"--target=x86_64", "--target-abi=gnu", "--cpu=x86-64-v2", nullptr};
  if (target == kAotTargetAndroidAarch64)
  {
    return androidAarch64;
  }
  if (target == kAotTargetAndroidX64)
  {
    return androidX64;
  }
  return nullptr;
}

static bool asksHostBudget(const std::string& wasmPath)
{
  std::ifstream in(wasmPath, std::ios::binary);
  std::vector<uint8_t> bytes(
      (std::istreambuf_iterator<char>(in)),
      std::istreambuf_iterator<char>());
  return exportsFunction(bytes, "__riveHostBudget");
}

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.
  const std::string& version = wamrcVersion();
  return m_cacheDir + "/" + version + "-r18-g" +
         std::to_string(WASM_RIVE_HW_GUARD_SIZE) + (m_wamrcTunes ? "t" : "");
}

// Device artifacts sit apart from this machine's, which share their names.
std::string ModuleTierLadder::artifactDir(const std::string& target)
{
  std::string dir = keyedCacheDir();
  if (!target.empty())
  {
    return dir + "/" + target;
  }
  // A host sharing the cache finds only code its cpu runs.
  return hostX86_64Level() >= 3 ? dir + "/x86-64-v3" : dir;
}

void ModuleTierLadder::createArtifactDir(const std::string& target)
{
  makeDir(m_cacheDir);
  makeDir(keyedCacheDir());
  makeDir(artifactDir(target));
}

std::string ModuleTierLadder::artifactName(
    uint64_t moduleKey,
    TierSpecies species)
{
  if (species == TierSpecies::o0)
  {
    return aotArtifactName(moduleKey, ".o0");
  }
  if (species == TierSpecies::hw)
  {
    return aotArtifactName(moduleKey, ".hw");
  }
  return aotArtifactName(moduleKey);
}

std::string ModuleTierLadder::artifactPath(
    uint64_t moduleKey,
    TierSpecies species,
    const std::string& target)
{
  std::unique_lock<std::mutex> lock(m_mutex);
  // Targets come from link peers, so only known ones reach a path.
  if (m_wamrcPath.empty() || m_cacheDir.empty() ||
      !trustedCacheDir(m_cacheDir) ||
      (!target.empty() && crossTargetArgs(target) == nullptr))
  {
    return std::string();
  }
  std::string path = artifactDir(target) + "/" +
                     artifactName(moduleKey, species);
  return fileExists(path) ? path : std::string();
}

#ifndef RIVE_NX
// Another process may still be using an older compiler's key dir this long
// after its last compile.
constexpr auto kStaleKeyDirAge = std::chrono::hours(24 * 7);
constexpr uintmax_t kKeyDirBytes = 512ull << 20;

// The names every keyedCacheDir has had: a wamrc version line, then a
// revision.
static bool isKeyDirName(const std::string& name)
{
  size_t revision = name.rfind("-r");
  if ((name.rfind("wamrc-", 0) != 0 && name.rfind("unknown-", 0) != 0) ||
      revision == std::string::npos)
  {
    return false;
  }
  std::string digits = name.substr(revision + 2);
  if (!digits.empty() && digits.back() == 't')
  {
    digits.pop_back();
  }
  return !digits.empty() &&
         digits.find_first_not_of("0123456789") == std::string::npos;
}

// Every module and every wamrc update leave artifacts behind, so stale key
// dirs go, then this one's oldest compiles until it fits.
static void pruneCache(
    const std::string& cacheDir,
    const std::string& keyedDir,
    bool staleKeyDirs)
{
  namespace fs = std::filesystem;
  std::error_code ec;
  auto staleBefore = fs::file_time_type::clock::now() - kStaleKeyDirAge;
  if (staleKeyDirs)
  {
    std::string current = fs::path(keyedDir).filename().string();
    std::vector<fs::path> stale;
    for (fs::directory_iterator it(cacheDir, ec), end; !ec && it != end;
         it.increment(ec))
    {
      std::string name = it->path().filename().string();
      std::error_code statError;
      if (name != current && isKeyDirName(name) &&
          it->is_directory(statError) &&
          it->last_write_time(statError) < staleBefore && !statError)
      {
        stale.push_back(it->path());
      }
    }
    for (const fs::path& dir : stale)
    {
      fs::remove_all(dir, ec);
    }
  }
  struct Artifact
  {
    fs::file_time_type written;
    uintmax_t size;
    fs::path path;
  };
  std::vector<Artifact> artifacts;
  std::vector<fs::path> staleMarkers;
  uintmax_t total = 0;
  ec.clear();
  for (fs::recursive_directory_iterator it(keyedDir, ec), end; !ec && it != end;
       it.increment(ec))
  {
    std::string extension = it->path().extension().string();
    std::error_code statError;
    // Each build leaves its own markers, so old ones expire like key dirs.
    if (extension == ".rejected" &&
        it->last_write_time(statError) < staleBefore && !statError)
    {
      staleMarkers.push_back(it->path());
    }
    else if (
        (extension == ".aot" || extension == ".wasm") &&
        it->is_regular_file(statError))
    {
      Artifact artifact{
          it->last_write_time(statError),
          it->file_size(statError),
          it->path()};
      if (!statError)
      {
        total += artifact.size;
        artifacts.push_back(std::move(artifact));
      }
    }
  }
  for (const fs::path& marker : staleMarkers)
  {
    fs::remove(marker, ec);
  }
  if (total <= kKeyDirBytes)
  {
    return;
  }
  std::sort(
      artifacts.begin(),
      artifacts.end(),
      [](const Artifact& a, const Artifact& b) {
        return a.written < b.written;
      });
  for (const Artifact& artifact : artifacts)
  {
    if (total <= kKeyDirBytes)
    {
      break;
    }
    if (fs::remove(artifact.path, ec))
    {
      total -= artifact.size;
    }
  }
}
#endif

// 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(processId()) + ".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())
  {
    std::remove(tmpPath.c_str());
    return false;
  }
  return publishFile(tmpPath, path);
}

TierCompile ModuleTierLadder::compileSync(
    uint64_t moduleKey,
    Span<const uint8_t> moduleBytes,
    TierSpecies species,
    const std::string& target,
    const std::atomic<bool>* cancel)
{
  TierCompile result;
  Job job{moduleKey, species};
  job.target = target;
  job.cancel = cancel;
  std::string cacheDir;
  std::string keyedDir;
  bool staleKeyDirs = false;
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    if (lookupLocked(job, result))
    {
      return result;
    }
    createArtifactDir(target);
    // Another user may have made the dir first.
    if (!enabledLocked())
    {
      result.reason = m_disabledReason;
      return result;
    }
    cacheDir = m_cacheDir;
    keyedDir = keyedCacheDir();
    job.wasmPath = keyedDir + "/" + wasmModuleName(moduleKey);
    if (!fileExists(job.wasmPath) &&
        !writeFileAtomic(job.wasmPath, moduleBytes))
    {
      result.reason = "could not write the module into the aot cache " +
                      m_cacheDir;
      m_failures[{moduleKey, species, target}] = result.reason;
      return result;
    }
    if (cancel != nullptr)
    {
      m_cancelableJobs.push_back(&job);
    }
  }
  auto compileStart = std::chrono::steady_clock::now();
  result.reason = runWamrc(job);
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    if (cancel != nullptr)
    {
      m_cancelableJobs.erase(
          std::find(m_cancelableJobs.begin(), m_cancelableJobs.end(), &job));
    }
    if (!result.reason.empty() && !job.cancelled)
    {
      m_failures[{moduleKey, species, target}] = result.reason;
    }
    if (result.reason.empty() && target.empty())
    {
      m_compiled.insert({moduleKey, species});
    }
    staleKeyDirs = result.reason.empty() && !m_pruned;
    m_pruned = m_pruned || staleKeyDirs;
  }
  if (result.reason.empty())
  {
    result.path = job.finalPath;
    result.compiled = true;
    if (target.empty())
    {
      auto compileMs = std::chrono::duration_cast<std::chrono::milliseconds>(
                           std::chrono::steady_clock::now() - compileStart)
                           .count();
      fprintf(
          stderr,
          "wasm aot: compiled %s in %lld ms\n",
          result.path.c_str(),
          (long long)compileMs);
    }
#ifndef RIVE_NX
    pruneCache(cacheDir, keyedDir, staleKeyDirs);
#endif
  }
  return result;
}

std::vector<TierCompile> ModuleTierLadder::compileAll(
    const std::vector<Span<const uint8_t>>& modules,
    TierSpecies species,
    const std::atomic<bool>* cancel)
{
  std::vector<uint64_t> keys;
  for (Span<const uint8_t> module : modules)
  {
    keys.push_back(wasmModuleKey(module));
  }
  std::vector<TierCompile> results(modules.size());
  std::vector<size_t> misses;
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    for (size_t i = 0; i < modules.size(); i++)
    {
      Job job{keys[i], species};
      if (!lookupLocked(job, results[i]))
      {
        misses.push_back(i);
      }
    }
  }
  auto compile = [&](size_t i) {
    if (cancel != nullptr && cancel->load())
    {
      results[i].reason = kCancelledReason;
      return;
    }
    results[i] = compileSync(
        keys[i],
        modules[i],
        species,
        std::string(),
        cancel);
  };
  std::vector<std::thread> threads;
  for (size_t i = 1; i < misses.size(); i++)
  {
    threads.emplace_back(compile, misses[i]);
  }
  if (!misses.empty())
  {
    compile(misses.front());
  }
  for (std::thread& thread : threads)
  {
    thread.join();
  }
  return results;
}

std::vector<TierCompile> ModuleTierLadder::compileWithLanes(
    Span<const uint8_t> moduleBytes,
    TierSpecies species,
    const std::atomic<bool>* cancel)
{
  std::vector<std::vector<uint8_t>> lanes = laneModules(moduleBytes);
  std::vector<Span<const uint8_t>> modules = {moduleBytes};
  for (const std::vector<uint8_t>& lane : lanes)
  {
    modules.emplace_back(lane.data(), lane.size());
  }
  return compileAll(modules, species, cancel);
}

bool ModuleTierLadder::lookupLocked(Job& job, TierCompile& result)
{
  if (!enabledLocked())
  {
    result.reason = m_disabledReason;
    return true;
  }
  if (!job.target.empty() && crossTargetArgs(job.target) == nullptr)
  {
    result.reason = "wamrc cannot compile for " + job.target;
    return true;
  }
  auto failure = m_failures.find({job.moduleKey, job.species, job.target});
  if (failure != m_failures.end())
  {
    result.reason = failure->second;
    return true;
  }
  job.finalPath = artifactDir(job.target) + "/" +
                  artifactName(job.moduleKey, job.species);
  if (fileExists(job.finalPath))
  {
    result.path = job.finalPath;
    return true;
  }
  std::ifstream rejected(rejectedMarker(job.finalPath));
  if (rejected && std::getline(rejected, result.reason))
  {
    m_failures[{job.moduleKey, job.species, job.target}] = result.reason;
    return true;
  }
  return false;
}

TierCompile ModuleTierLadder::bootCompile(
    uint64_t moduleKey,
    Span<const uint8_t> moduleBytes,
    TierSpecies species)
{
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    if (!m_compileOnBoot)
    {
      TierCompile result;
      Job job{moduleKey, species};
      if (!lookupLocked(job, result))
      {
        result.reason = "no aot artifact cached for this module yet";
      }
      return result;
    }
  }
  // The boot loads its lanes next, and compiles of one module never merge,
  // so they all finish before it returns.
  return compileWithLanes(moduleBytes, species).front();
}

bool ModuleTierLadder::failed(
    uint64_t moduleKey,
    TierSpecies species,
    const std::string& target)
{
  std::unique_lock<std::mutex> lock(m_mutex);
  return m_failures.count({moduleKey, species, target}) != 0;
}

void ModuleTierLadder::rejectArtifact(
    uint64_t moduleKey,
    TierSpecies species,
    const std::string& reason)
{
  std::unique_lock<std::mutex> lock(m_mutex);
  m_failures[{moduleKey, species, std::string()}] = reason;
  if (m_cacheDir.empty())
  {
    return;
  }
  std::string path = artifactDir(std::string()) + "/" +
                     artifactName(moduleKey, species);
  std::remove(path.c_str());
  // A recompile would make the same artifact again, so later sessions skip
  // it. One an older session left, maybe torn, compiles afresh.
  if (m_compiled.count({moduleKey, species}) != 0)
  {
    writeFileAtomic(
        rejectedMarker(path),
        Span<const uint8_t>((const uint8_t*)reason.data(), reason.size()));
  }
}

void ModuleTierLadder::cancelCompiles()
{
  std::unique_lock<std::mutex> lock(m_mutex);
  for (Job* job : m_cancelableJobs)
  {
    if (job->cancel == nullptr || !job->cancel->load())
    {
      continue;
    }
    job->cancelled = true;
    if (job->child != -1)
    {
      killChild(job->child);
    }
  }
}

std::string ModuleTierLadder::runWamrc(Job& job)
{
  // Callers dropped m_mutex; only job fields and immutable config are
  // touched off-lock, except child which cancelCompiles reads under
  // lock.
  const std::string& finalPath = job.finalPath;
  std::string wamrc;
  std::string cacheDir;
  [[maybe_unused]] bool tunes = false;
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    wamrc = m_wamrcPath;
    cacheDir = m_cacheDir;
    tunes = m_wamrcTunes;
  }
  // Unique temp per compile: the same artifact can be raced by two boots
  // on different threads, or by two processes sharing the cache.
  static std::atomic<uint64_t> tmpSerial{0};
  std::string tmpPath = finalPath + "." + std::to_string(processId()) + "-" +
                        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");
    args.push_back(wamrcHwGuardFlag());
  }
  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)
  {
    args.push_back("--opt-level=0");
  }
  else
  {
    args.push_back("--opt-level=3");
  }
  if (!job.target.empty())
  {
    const char* const* targetArgs = crossTargetArgs(job.target);
    if (targetArgs == nullptr)
    {
      return "wamrc cannot compile for " + job.target;
    }
    for (; *targetArgs != nullptr; targetArgs++)
    {
      args.push_back(*targetArgs);
    }
  }
#if (defined(__APPLE__) || defined(_WIN32)) &&                                 \
    (defined(__aarch64__) || defined(_M_ARM64))
  else
  {
    // 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");
#if defined(__APPLE__)
    // Every Apple silicon Mac has single instruction atomics, which make
    // parallel calls' barriers cheaper than load and store exclusive loops.
    args.push_back("--cpu-features=+reserve-x18,+lse");
#else
    args.push_back("--cpu-features=+reserve-x18");
#endif
#if defined(__APPLE__)
    // Generic scheduling turns float compare chains into mispredicted
    // branches (up to 1.5x slower); tuning leaves the ISA baseline alone.
    if (tunes)
    {
      args.push_back("--tune-cpu=apple-m1");
    }
#endif
  }
#elif defined(__x86_64__) || defined(_M_X64)
  else
  {
    // Left alone wamrc targets this machine's exact cpu, which the cache
    // does not key. Without FMA, relaxed madd calls fmaf.
    args.push_back("--target=x86_64");
    args.push_back(
        hostX86_64Level() >= 3 ? "--cpu=x86-64-v3" : "--cpu=x86-64-v2");
#if defined(__APPLE__)
    // Code maps above 4GB here, out of reach of 32 bit relocations.
    args.push_back("--size-level=0");
#elif defined(_WIN32)
    // wamrc's own default for this host, which naming a target drops.
    args.push_back("--size-level=1");
#endif
  }
#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::string failure;
  intptr_t child = startChild(args, &failure);
  if (child == -1)
  {
    fprintf(stderr, "[wasm] %s\n", failure.c_str());
    return failure;
  }
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    job.child = child;
    // A cancel that landed before the spawn had nothing to kill.
    if (job.cancel != nullptr && job.cancel->load())
    {
      job.cancelled = true;
    }
    if (job.cancelled)
    {
      killChild(child);
    }
  }
  int exitCode = waitChild(child);
  {
    std::unique_lock<std::mutex> lock(m_mutex);
    job.child = -1;
  }
  releaseChild(child);
  if (job.cancelled || exitCode != 0)
  {
    std::remove(tmpPath.c_str());
    if (job.cancelled)
    {
      return kCancelledReason;
    }
    // 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",
        exitCode,
        job.wasmPath.c_str());
    return "wamrc could not compile the module";
  }
  // Atomic arrival: a partial artifact can never carry the final name.
  if (!publishFile(tmpPath, finalPath))
  {
    return "could not write the artifact into the aot cache " + cacheDir;
  }
  return std::string();
}

} // namespace rive

#endif // RIVE_WASM_TIER_LADDER
#endif // WITH_RIVE_SCRIPTING_WASM
