#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/viewmodel/viewmodel_instance.hpp"
#include "rive/async/work_pool.hpp"
#ifdef RIVE_CANVAS
#include "rive/renderer/render_context.hpp"
#endif
#include "lualib.h"
#include <stdio.h>
#include <unordered_set>
#include <string>
#include <string_view>
#include <queue>
#include <vector>
#include <algorithm>
#include <array>
#include <iterator>

using namespace rive;

int luaopen_rive_base(lua_State* L);
int luaopen_rive_math(lua_State* L);
int luaopen_rive_renderer_library(lua_State* L);
int luaopen_rive_properties(lua_State* L);
int luaopen_rive_artboards(lua_State* L);
int luaopen_rive_data_values(lua_State* L);
int luaopen_rive_data_context(lua_State* L);
int luaopen_rive_input(lua_State* L);
int luaopen_rive_contex(lua_State* L);
int luaopen_rive_audio(lua_State* L);
extern "C" int luaopen_rive_buffer_ext(lua_State* L);

static const luaL_Reg lualibs[] = {
    {"", luaopen_base},
    {LUA_TABLIBNAME, luaopen_table},
    {LUA_MATHLIBNAME, luaopen_math},
    {"rive", luaopen_rive_base},
    {LUA_OSLIBNAME, luaopen_os},
    {LUA_STRLIBNAME, luaopen_string},
    {LUA_UTF8LIBNAME, luaopen_utf8},
    {LUA_BUFFERLIBNAME, luaopen_buffer},
    {LUA_BITLIBNAME, luaopen_bit32},
    {"math", luaopen_rive_math},
    {"renderer", luaopen_rive_renderer_library},
    {"properties", luaopen_rive_properties},
    {"artboard", luaopen_rive_artboards},
    {"dataValue", luaopen_rive_data_values},
    {"input", luaopen_rive_input},
    {"context", luaopen_rive_contex},
    {"dataContext", luaopen_rive_data_context},
    {"audio", luaopen_rive_audio},
    {"promise", luaopen_rive_promise},
    {NULL, NULL},
};

namespace rive
{
int luaopen_rive(lua_State* L)
{
    lua_callbacks(L)->useratom =
        [](lua_State*, const char* s, size_t l) -> int16_t {
        return rive_lua_findAtom(s, l);
    };

    const luaL_Reg* lib = lualibs;
    for (; lib->func; lib++)
    {
        lua_pushcfunction(L, lib->func, NULL);
        lua_pushstring(L, lib->name);
        lua_call(L, 1, 0);
    }

    // Extend the buffer library with SIMD-accelerated functions
    // (readf16, writef16, stridedcopy, convert).
    luaopen_rive_buffer_ext(L);

    return 0;
}

int rive_luaErrorHandler(lua_State* L)
{
    ScriptingContext* context =
        static_cast<ScriptingContext*>(lua_getthreaddata(L));
    context->printError(L);

    // Optionally, you can push a new value onto the stack to be returned by
    // lua_pcall For example, push a specific error code or a more detailed
    // message
    const char* error = lua_tostring(L, -1);
    lua_pushstring(L, error);
    return 1; // Number of return values
    // return 0;
}

int rive_lua_pcall(lua_State* state, int nargs, int nresults)
{
    ScriptingContext* context =
        static_cast<ScriptingContext*>(lua_getthreaddata(state));

    int ret = context->pCall(state, nargs, nresults);
#ifdef RIVE_ORE
    rive_lua_closeOrphanRenderPass(state);
    rive_lua_closeOrphanCanvasFrames(state);
#endif
    return ret;
}

int rive_lua_pcall_with_context(lua_State* state,
                                ScriptedObject* scriptedObject,
                                int nargs,
                                int nresults)
{
    ScriptingContext* context =
        static_cast<ScriptingContext*>(lua_getthreaddata(state));
    ScopedScriptedObjectContext scope(context, scriptedObject);
    int ret = context->pCall(state, nargs, nresults);
#ifdef RIVE_ORE
    rive_lua_closeOrphanRenderPass(state);
    rive_lua_closeOrphanCanvasFrames(state);
#endif
    return ret;
}

int rive_lua_pushRef(lua_State* state, int ref)
{
    lua_checkstack(state, 1);
    return lua_rawgeti(state, luaRegistryIndex, ref);
}

void rive_lua_pop(lua_State* state, int count)
{
    lua_settop(state, -count - 1);
}

static void* l_alloc(void* ud, void* ptr, size_t osize, size_t nsize)
{
    (void)ud;
    (void)osize;
    if (nsize == 0)
    {
        free(ptr);
        // delete[] (uint8_t*)ptr;
        return NULL;
    }
    else
    {
        // auto nptr = new uint8_t[nsize];
        // memcpy(nptr, ptr, std::min(nsize, osize));
        // delete[] (uint8_t*)ptr;
        // return nptr;
        return realloc(ptr, nsize);
    }
}

static const char* registeredCacheTableKey = "_MODULES";

static int checkRegisteredModules(lua_State* L, const char* path)
{
    luaL_findtable(L, LUA_REGISTRYINDEX, registeredCacheTableKey, 1);
    lua_getfield(L, -1, path);
    if (lua_isnil(L, -1))
    {
        lua_pop(L, 2);
        return 0;
    }

    lua_remove(L, -2);
    return 1;
}

static int lua_requireinternal(lua_State* L, const char* requirerChunkname)
{
    // Discard extra arguments, we only use path
    lua_settop(L, 1);
    const char* path = luaL_checkstring(L, 1);

    ScriptingContext* context =
        static_cast<ScriptingContext*>(lua_getthreaddata(L));

    if (checkRegisteredModules(L, path) == 1)
    {
        return 1;
    }

    // Record missing dependency if we're registering a module
    if (requirerChunkname != nullptr && context != nullptr)
    {
        context->recordMissingDependency(requirerChunkname, path);
    }

    luaL_error(L, "require could not find a script named %s", path);
    return 0;
}

static int lua_require(lua_State* L)
{
    lua_Debug ar;
    int level = 1;

    do
    {
        if (!lua_getinfo(L, level++, "s", &ar))
        {
            luaL_error(L, "require is not supported in this context");
        }
    } while (ar.what[0] == 'C');

    return lua_requireinternal(L, ar.source);
}

static int luaR_error(lua_State* L)
{
    int level = luaL_optinteger(L, 2, 1);
    lua_settop(L, 1);
    if (lua_isstring(L, 1) && level > 0)
    {
        luaL_where(L, level);
        lua_pushvalue(L, 1);
        lua_concat(L, 2);
    }
    lua_error(L);
}

static int lua_late(lua_State* L)
{
    lua_pushnil(L);
    return 1;
}

void ScriptingVM::init(lua_State* state, ScriptingContext* context)
{
    luaopen_rive(state);
    lua_setthreaddata(state, context);

    lua_pushcclosurek(state, lua_require, "require", 0, nullptr);
    lua_setglobal(state, "require");

    lua_pushcclosurek(state, luaR_error, "error", 0, nullptr);
    lua_setglobal(state, "error");

    lua_pushcclosurek(state, lua_late, "late", 0, nullptr);
    lua_setglobal(state, "late");

    luaL_sandbox(state);
    luaL_sandboxthread(state);
}

ScriptingVM::ScriptingVM(std::unique_ptr<ScriptingContext> context) :
    m_ownedContext(std::move(context))
{
    m_state = lua_newstate(l_alloc, nullptr);
    init(m_state, m_ownedContext.get());
}

ScriptingVM::~ScriptingVM() { closeLuaState(); }

void ScriptingVM::closeLuaState()
{
    if (m_state == nullptr)
    {
        return;
    }
    // Cancel async tasks before closing Lua state to prevent callbacks
    // from accessing dead state.
    if (m_ownedContext)
        m_ownedContext->shutdownAsyncForState(m_state);

    // Null every registered ScriptedObject's back-pointer before the lua
    // teardown cascade. Once m_vm is gone, scriptDispose() (called from
    // cascading destruction inside lua_close) skips its releaseRef /
    // disposeScriptedContext calls. Those calls would otherwise dereference
    // Lua userdatas (ScriptedContext, ref tables) that lua_close has already
    // freed in earlier sweep iterations.
    detachScriptedObjects();

    lua_State* state = m_state;
    m_state = nullptr;
    lua_close(state);
}

void ScriptingVM::replaceContext(std::unique_ptr<ScriptingContext> newContext)
{
#ifdef WITH_RIVE_TOOLS
    if (m_ownedContext != nullptr)
    {
        m_ownedContext->disposeOrphanScriptedProperties();
    }
#endif
    m_ownedContext = std::move(newContext);
    lua_setthreaddata(m_state, m_ownedContext.get());
}

void ScriptingVM::addModule(ModuleDetails* moduleDetails)
{
    context()->addModule(moduleDetails);
}

void ScriptingVM::performRegistration()
{
    context()->performRegistration(m_state);
}

// Loads bytecode into a sandboxed thread without executing it.
// On success, pushes the module thread (with loaded closure) onto L's stack.
// Returns true on success.
bool ScriptingVM::loadModule(lua_State* L,
                             const char* name,
                             Span<uint8_t> bytecode)
{
    if (bytecode.empty())
    {
        return false;
    }
    // module needs to run in a new thread, isolated from the rest
    // note: we create ML on main thread so that it doesn't inherit environment
    // of L
    lua_State* GL = lua_mainthread(L);
    lua_State* ML = lua_newthread(GL);
    lua_xmove(GL, L, 1);
    // new thread needs to have the globals sandboxed
    luaL_sandboxthread(ML);
    lua_setthreaddata(ML, lua_getthreaddata(L));

    int status =
        luau_load(ML, name, (const char*)bytecode.data(), bytecode.size(), 0);

    if (status != 0)
    {
        // luau_load failed — error string is on ML stack
        lua_xmove(ML, L, 1);
        ScriptingContext* context =
            static_cast<ScriptingContext*>(lua_getthreaddata(L));
        context->printError(L);
        lua_pop(L, 2); // pop error + thread
        return false;
    }

    // Thread with loaded closure is on top of L's stack.
    return true;
}

// Executes a previously loaded module thread (on top of L's stack from
// loadModule). On success, replaces the thread with the module result.
// If isUtility, also registers the result in the require cache.
// Returns true on success.
bool ScriptingVM::executeModule(lua_State* L,
                                const char* name,
                                bool isUtility,
                                const char* chunkname)
{
    const char* display = chunkname != nullptr ? chunkname : name;

    // The module thread should be on top of the stack.
    lua_State* ML = lua_tothread(L, -1);
    if (ML == nullptr)
    {
        return false;
    }

    int status = lua_resume(ML, L, 0);
    if (status == 0)
    {
        if (lua_gettop(ML) == 0)
        {
            lua_pushfstring(ML, "%s:1: module must return a value", display);
        }
        else if (!lua_istable(ML, -1) && !lua_isfunction(ML, -1))
        {
            lua_pushfstring(ML,
                            "%s:1: module must return a table or function",
                            display);
        }
    }
    else if (status == LUA_YIELD)
    {
        lua_pushfstring(ML, "%s:1: module can not yield", display);
    }
    else if (!lua_isstring(ML, -1))
    {
        lua_pushfstring(ML,
                        "%s:1: unknown error while running module",
                        display);
    }

    // add ML result to L stack
    lua_xmove(ML, L, 1);
    // An error occurred if the top of the stack is a string.
    if (lua_isstring(L, -1))
    {
        ScriptingContext* context =
            static_cast<ScriptingContext*>(lua_getthreaddata(L));
        context->printError(L);
        lua_pop(L, 2); // pop error + thread
        return false;
    }
    // remove ML thread from L stack
    lua_remove(L, -2);
    // added one value to L stack: module result

    if (isUtility)
    {
        // Register into the require cache directly.
        luaL_findtable(L, LUA_REGISTRYINDEX, registeredCacheTableKey, 1);
        lua_pushstring(L, name);
        lua_pushvalue(L, -3); // copy module result (below cache table + name)
        lua_settable(L, -3);  // cache[name] = result
        lua_pop(L, 1);        // pop cache table
    }

    return true;
}

static void dump_stack(lua_State* state)
{
    int i;
    int top = lua_gettop(state);
    for (i = 1; i <= top; i++)
    { /* repeat for each level */
        int t = lua_type(state, i);
        switch (t)
        {

            case LUA_TSTRING: /* strings */
                fprintf(stderr,
                        "  (%i)[STRING] %s\n",
                        i,
                        lua_tostring(state, i));
                break;

            case LUA_TBOOLEAN: /* booleans */
                fprintf(stderr,
                        "  (%i)[BOOLEAN] %s\n",
                        i,
                        lua_toboolean(state, i) ? "true" : "false");
                break;

            case LUA_TNUMBER: /* numbers */
                fprintf(stderr,
                        "  (%i)[NUMBER] %g\n",
                        i,
                        lua_tonumber(state, i));
                break;

            default: /* other values */
                fprintf(stderr, "  (%i)[%s]\n", i, lua_typename(state, t));
                break;
        }
    }
    fprintf(stderr, "\n"); /* end the listing */
}

void ScriptingVM::dumpStack(lua_State* state) { dump_stack(state); }

void ScriptingContext::addModule(ModuleDetails* moduleDetails)
{
    m_modulesToRegister.push_back(moduleDetails);
    m_moduleLookup[moduleDetails->moduleName()] = moduleDetails;
}

bool ScriptingContext::tryRegisterModule(lua_State* state,
                                         ModuleDetails* moduleDetails)
{
#ifndef WITH_RIVE_TOOLS
    // In production builds, only allow verified (signed) scripts
    if (!moduleDetails->verified())
    {
        return false;
    }
#endif
    std::string name = moduleDetails->moduleName();
    bool registerSuccess = false;
    int functionRef = 0;
    if (moduleDetails->isProtocolScript())
    {
        if (ScriptingVM::registerScript(state,
                                        name.c_str(),
                                        moduleDetails->moduleBytecode()))
        {
            // registerScript leaves the function on the stack
            if (static_cast<lua_Type>(lua_type(state, -1)) == LUA_TFUNCTION)
            {
                functionRef = lua_ref(state, -1);
            }
            lua_pop(state, 1);
            registerSuccess = true;
        }
    }
    else
    {
        if (ScriptingVM::registerModule(state,
                                        name.c_str(),
                                        moduleDetails->moduleBytecode()))
        {
            registerSuccess = true;
        }
    }
    if (registerSuccess)
    {
        moduleDetails->registrationComplete(functionRef);
        onModuleRegistered(moduleDetails);
        return true;
    }

    return false;
}

void ScriptingContext::performRegistration(lua_State* state)
{
    // Loop over all of the modules once. We need do a tryRegister
    // pass on each module in order to determine if it has any
    // required dependencies
    for (ModuleDetails* moduleDetails : m_modulesToRegister)
    {
        if (moduleDetails == nullptr)
        {
            continue;
        }
        std::string cacheKey = moduleDetails->moduleName();

        // Skip if already registered
        if (checkRegisteredModules(state, cacheKey.c_str()) == 1)
        {
            lua_pop(state, 1);
            continue;
        }
        tryRegisterModule(state, moduleDetails);
    }

    // One cleanup pass: producers emit modules in dependency order (the
    // editor and rive-cli both sort), so a single sorted retry suffices.
    if (!m_pendingModules.empty())
    {
        std::vector<ModuleDetails*> pendingModules;
        for (auto module : m_pendingModules)
        {
            pendingModules.push_back(module);
        }
        std::vector<ModuleDetails*> sortedModules;
        std::unordered_set<ModuleDetails*> visitedModules;

        ModuleDetails* module = pendingModules.back();
        pendingModules.pop_back();
        sortNextModule(module,
                       &pendingModules,
                       &sortedModules,
                       &visitedModules);

        // Register modules in sorted order
        for (ModuleDetails* moduleDetails : sortedModules)
        {
            // Skip utility modules that already made it into the cache.
            if (checkRegisteredModules(state,
                                       moduleDetails->moduleName().c_str()) ==
                1)
            {
                lua_pop(state, 1);
                continue;
            }
            // A known-missing require has not registered yet; re-running
            // the chunk would repeat its side effects and error.
            if (!moduleDetails->missingDependencies().empty())
            {
                continue;
            }
            tryRegisterModule(state, moduleDetails);
        }
    }

    m_modulesToRegister.clear();
    m_pendingModules.clear();
}

void ScriptingContext::sortNextModule(
    ModuleDetails* module,
    std::vector<ModuleDetails*>* pendingModules,
    std::vector<ModuleDetails*>* sortedModules,
    std::unordered_set<ModuleDetails*>* visitedModules)
{
    // If already visited, skip
    if (visitedModules->find(module) != visitedModules->end())
    {
        return;
    }

    auto dependencies = module->missingDependencies();
    for (const auto& dependencyName : dependencies)
    {
        auto lookupIt = m_moduleLookup.find(dependencyName);
        if (lookupIt != m_moduleLookup.end())
        {
            ModuleDetails* dependencyModule = lookupIt->second;
            // Recursively process the dependency
            sortNextModule(dependencyModule,
                           pendingModules,
                           sortedModules,
                           visitedModules);
        }
    }

    if (std::find(sortedModules->begin(), sortedModules->end(), module) ==
        sortedModules->end())
    {
        sortedModules->push_back(module);
    }
    visitedModules->insert(module);
    if (!pendingModules->empty())
    {
        ModuleDetails* nextModule = pendingModules->back();
        pendingModules->pop_back();
        sortNextModule(nextModule,
                       pendingModules,
                       sortedModules,
                       visitedModules);
    }
}

void ScriptingContext::recordMissingDependency(
    const std::string& requiringModule,
    const std::string& missingModule)
{
    if (requiringModule.empty())
    {
        return;
    }
    auto it = m_moduleLookup.find(requiringModule);
    if (it == m_moduleLookup.end())
    {
        return;
    }
    it->second->addMissingDependency(missingModule);
    m_pendingModules.insert(it->second);
}

void ScriptingContext::onModuleRegistered(ModuleDetails* moduleDetails)
{
    std::string key = moduleDetails->moduleName();
    for (ModuleDetails* module : m_modulesToRegister)
    {
        if (!module->missingDependencies().empty())
        {
            module->clearMissingDependency(key);
        }
    }
    auto it = m_pendingModules.find(moduleDetails);
    if (it != m_pendingModules.end())
    {
        m_pendingModules.erase(it);
    }
}

#ifdef WITH_RIVE_TOOLS
void ScriptingContext::registerShaderRstb(std::string name,
                                          std::vector<uint8_t> bytes)
{
    m_shaderRstbs[std::move(name)] = std::move(bytes);
}

const std::vector<uint8_t>* ScriptingContext::findShaderRstb(
    const std::string& name) const
{
    auto it = m_shaderRstbs.find(name);
    return it != m_shaderRstbs.end() ? &it->second : nullptr;
}

const std::vector<uint8_t>* ScriptingContext::findShaderRstb(
    const ScopedAssetReference& reference) const
{
    const std::vector<uint8_t>* found = nullptr;
    int bestRank = 0;
    for (const auto& entry : m_shaderRstbs)
    {
        size_t slash = entry.first.rfind('/');
        std::string shortName = slash == std::string::npos
                                    ? entry.first
                                    : entry.first.substr(slash + 1);
        int rank = reference.match(entry.first, shortName);
        if (rank > bestRank)
        {
            bestRank = rank;
            found = &entry.second;
        }
    }
    return found;
}

void ScriptingContext::setGeneratorRef(uint32_t assetId, int ref)
{
    m_assetGeneratorRefs[assetId] = ref;
}

int ScriptingContext::getGeneratorRef(uint32_t assetId) const
{
    auto it = m_assetGeneratorRefs.find(assetId);
    return it != m_assetGeneratorRefs.end() ? it->second : 0;
}

void ScriptingContext::clearGeneratorRefs() { m_assetGeneratorRefs.clear(); }

bool ScriptingContext::hasGeneratorRef(uint32_t assetId) const
{
    return m_assetGeneratorRefs.find(assetId) != m_assetGeneratorRefs.end();
}

void ScriptingContext::trackOrphanScriptedProperty(ScriptedProperty* property)
{
    if (property != nullptr)
    {
        m_orphanScriptedProperties.push_back(property);
    }
}

void ScriptingContext::untrackOrphanScriptedProperty(ScriptedProperty* property)
{
    auto it = std::remove(m_orphanScriptedProperties.begin(),
                          m_orphanScriptedProperties.end(),
                          property);
    m_orphanScriptedProperties.erase(it, m_orphanScriptedProperties.end());
}

void ScriptingContext::disposeOrphanScriptedProperties()
{
    auto orphans = m_orphanScriptedProperties;
    for (ScriptedProperty* property : orphans)
    {
        if (property != nullptr)
        {
            property->dispose();
        }
    }
    m_orphanScriptedProperties.clear();
}

void ScriptingContext::disposeOrphanScriptedProperties(uint32_t tag)
{
    if (tag == 0)
    {
        return;
    }
    // dispose() untracks each property, so iterate a copy.
    auto orphans = m_orphanScriptedProperties;
    for (ScriptedProperty* property : orphans)
    {
        if (property != nullptr && property->orphanOwnerTag() == tag)
        {
            property->dispose();
        }
    }
}
#endif

void ScriptingContext::trackViewModelInstance(rcp<ViewModelInstance> instance)
{
    if (instance == nullptr)
    {
        return;
    }
    auto& tracked = m_trackedViewModelInstances[instance.get()];
    tracked.instance = instance;
    tracked.registrations++;
}

void ScriptingContext::untrackViewModelInstance(ViewModelInstance* instance)
{
    if (instance == nullptr)
    {
        return;
    }
    auto it = m_trackedViewModelInstances.find(instance);
    if (it != m_trackedViewModelInstances.end() &&
        --it->second.registrations <= 0)
    {
        m_trackedViewModelInstances.erase(it);
    }
}

void ScriptingContext::advanceDetachedViewModels()
{
    for (auto& entry : m_trackedViewModelInstances)
    {
        ViewModelInstance* instance = entry.second.instance.get();
        // Only advance detached roots. Instances with parents are already
        // reached through the bound tree or their detached-root ancestor.
        if (!instance->hasParents())
        {
            instance->advanced();
        }
    }
}

// ── WorkPool integration ───────────────────────────────────────────────────
// getGlobalWorkPool() is defined in work_pool.cpp (shared singleton).

WorkPool* ScriptingContext::workPool()
{
    if (m_ownerId == 0)
        m_ownerId = WorkPool::nextOwnerId();
    return getGlobalWorkPool().get();
}

// Forward-declared in lua_image_decode.cpp (WASM only).
#ifdef __EMSCRIPTEN__
extern void wasm_cancelPendingDecodes(lua_State* mainThread);
#endif

void ScriptingContext::shutdownAsync()
{
    if (m_ownerId != 0)
    {
        auto& pool = getGlobalWorkPoolIfExists();
        if (pool)
            pool->cancelAllForOwner(m_ownerId);
        m_ownerId = 0;
    }
}

// Called from ~ScriptingVM before lua_close. On WASM, also cancel
// browser-native image decodes that bypass WorkPool.
void ScriptingContext::shutdownAsyncForState(lua_State* mainThread)
{
    shutdownAsync();
#ifdef __EMSCRIPTEN__
    wasm_cancelPendingDecodes(mainThread);
#endif
}

bool ScriptingVM::registerScript(lua_State* state,
                                 const char* name,
                                 Span<uint8_t> bytecode,
                                 const char* chunkname)
{
    // Check if already registered - leave module on stack for caller to use
    if (checkRegisteredModules(state, name) == 1)
    {
        return true;
    }

    if (!loadModule(state, chunkname != nullptr ? chunkname : name, bytecode))
    {
        return false;
    }

    if (!executeModule(state, name, false, chunkname))
    {
        return false;
    }

    return true;
}

bool ScriptingVM::registerModule(lua_State* state,
                                 const char* name,
                                 Span<uint8_t> bytecode,
                                 const char* chunkname)
{
    // Check if already registered
    if (checkRegisteredModules(state, name) == 1)
    {
        lua_pop(state, 1);
        return true;
    }

    if (!loadModule(state, chunkname != nullptr ? chunkname : name, bytecode))
    {
        return false;
    }

    if (!executeModule(state, name, true, chunkname))
    {
        return false;
    }

    // executeModule with isUtility=true registers into the require cache
    // and leaves the module result on the stack. Pop it.
    lua_pop(state, 1);
    return true;
}

void ScriptingVM::unregisterModule(lua_State* state, const char* name)
{
    luaL_findtable(state, LUA_REGISTRYINDEX, registeredCacheTableKey, 1);
    lua_pushstring(state, name);
    lua_pushnil(state);
    lua_settable(state, -3);
    lua_pop(state, 1);
}

void ScriptingVM::unregisterModule(const char* name)
{
    return unregisterModule(m_state, name);
}

bool ScriptingVM::registerModule(const char* name, Span<uint8_t> bytecode)
{
    return registerModule(m_state, name, bytecode);
}

bool ScriptingVM::registerScript(const char* name, Span<uint8_t> bytecode)
{
    return registerScript(m_state, name, bytecode);
}

int CPPRuntimeScriptingContext::pCall(lua_State* state, int nargs, int nresults)
{
    // calculate stack position for message handler
    int hpos = lua_gettop(state) - nargs;
    lua_pushcfunction(state, rive_luaErrorHandler, "riveErrorHandler");
    lua_insert(state, hpos);

    startTimedExecution(state);
    int ret = lua_pcall(state, nargs, nresults, hpos);
    endTimedExecution(state);
    lua_remove(state, hpos);
    return ret;
}

} // namespace rive
#endif
