#ifdef WITH_RIVE_SCRIPTING
// ScriptingVM's implementation of the ScriptBackend seam: the Lua mechanics
// that used to live inline in the scripted core objects.
#include "rive/lua/rive_lua_libs.hpp"

#include "rive/animation/listener_invocation.hpp"
#include "rive/artboard.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/file.hpp"
#include "rive/scripted/scripted_object.hpp"
#include "rive/shapes/paint/shape_paint.hpp"

using namespace rive;

void ScriptingVM::releaseRef(int ref)
{
    if (m_state != nullptr && ref != 0)
    {
        lua_unref(m_state, ref);
    }
}

int ScriptingVM::resolveGeneratorRef(int ref) const
{
#ifdef WITH_RIVE_TOOLS
    if (m_state != nullptr)
    {
        auto context =
            static_cast<ScriptingContext*>(lua_getthreaddata(m_state));
        if (context != nullptr && context->hasGeneratorRef(ref))
        {
            return context->getGeneratorRef(ref);
        }
    }
#endif
    return ref;
}

int ScriptingVM::instantiate(int generatorRef,
                             ScriptedObject* object,
                             int* outContextRef,
                             ScriptedContext** outContextPtr)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, generatorRef);

    // Create the Context userdata before calling the generator so scripts
    // can request resources at construction time (e.g.
    // `return { canvas = context:gpuCanvas() }`). The same Context is reused
    // when init(self, context) is called, so a script only ever sees one
    // Context per scripted-object lifetime.
    // Stack: [generator]
    ScriptedContext* contextPtr = lua_newrive<ScriptedContext>(L, object);
    // Stack: [generator, context]
    int contextRef = lua_ref(L, -1);
    // Stack: [generator, context]  (lua_ref does not pop)

    auto disposeContext = [&]() {
        contextPtr->clearScriptedObject();
        lua_unref(L, contextRef);
    };

    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 1, 1)) !=
        LUA_OK)
    {
        disposeContext();
        rive_lua_pop(L, 1);
        return 0;
    }
    if (static_cast<lua_Type>(lua_type(L, -1)) != LUA_TTABLE)
    {
        disposeContext();
        rive_lua_pop(L, 1);
        return 0;
    }
    int selfRef = lua_ref(L, -1);
    rive_lua_pop(L, 1);
    *outContextRef = contextRef;
    *outContextPtr = contextPtr;
    return selfRef;
}

ScriptBackend::InitResult ScriptingVM::callUserInit(ScriptedObject* object,
                                                    int selfRef,
                                                    int contextRef)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, "init")) != LUA_TFUNCTION)
    {
        // init is optional and not implemented (assumed for legacy files);
        // nothing to run — the object is considered initialized.
        rive_lua_pop(L, 2); // non-function field + self
        return InitResult::notImplemented;
    }
    // Stack: [self, field]
    lua_pushvalue(L, -2);
    // Stack: [self, field, self]
    rive_lua_pushRef(L, contextRef);
    // Stack: [self, field, self, ScriptedContext]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 2, 1)) !=
        LUA_OK)
    {
        // Stack: [self, status]
        rive_lua_pop(L, 2);
        return InitResult::failed;
    }
    if (!lua_toboolean(L, -1) || object->m_contextPtr->missingRequestedData())
    {
        rive_lua_pop(L, 2);
        return InitResult::failed;
    }
    // Stack: [self, result]
    rive_lua_pop(L, 1);
    assert(static_cast<lua_Type>(lua_type(L, -1)) == LUA_TTABLE);
    // Stack: [self]
    rive_lua_pop(L, 1);
    return InitResult::succeeded;
}

bool ScriptingVM::callAdvance(ScriptedObject* object,
                              int selfRef,
                              float elapsedSeconds)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    // implementedMethods may be assumed for legacy files (all-bits default);
    // if the field isn't actually a function, treat it as not implemented.
    if (static_cast<lua_Type>(lua_getfield(L, -1, "advance")) != LUA_TFUNCTION)
    {
        rive_lua_pop(L, 2); // non-function field + self
        return false;
    }
    lua_pushvalue(L, -2);
    lua_pushnumber(L, elapsedSeconds);
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 2, 1)) !=
        LUA_OK)
    {
        rive_lua_pop(L, 2);
        return false;
    }
    bool result = lua_toboolean(L, -1);
    rive_lua_pop(L, 2);
    return result;
}

void ScriptingVM::callUpdate(ScriptedObject* object, int selfRef)
{
    lua_State* L = m_state;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, "update")) != LUA_TFUNCTION)
    {
        // Not actually implemented (assumed for legacy files); no-op. The
        // update phase never started, so there's no flag to reset.
        rive_lua_pop(L, 2); // non-function field + self
        return;
    }
    // Only inside the update phase while the callback actually runs.
    object->setInUpdatePhase(true);
    // Stack: [self, field] Swap self and field
    lua_insert(L, -2);
    // Stack: [field, self]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 1, 0)) !=
        LUA_OK)
    {
        rive_lua_pop(L, 1);
    }
    object->setInUpdatePhase(false);
}

void ScriptingVM::callTrigger(ScriptedObject* object,
                              int selfRef,
                              const char* name)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    if (static_cast<lua_Type>(lua_getfield(L, -1, name)) != LUA_TFUNCTION)
    {
        rive_lua_pop(L, 2);
        return;
    }
    lua_pushvalue(L, -2);
    rive_lua_pcall_with_context(L, object, 1, 0);
    rive_lua_pop(L, 1);
}

bool ScriptingVM::callNumberMethod(ScriptedObject* object,
                                   int selfRef,
                                   const char* name,
                                   const float* args,
                                   size_t argCount,
                                   float* outResult)
{
    lua_State* L = m_state;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, name)) != LUA_TFUNCTION)
    {
        rive_lua_pop(L, 2); // non-function field + self
        return false;
    }
    // Stack: [self, method]
    lua_pushvalue(L, -2);
    // Stack: [self, method, self]
    for (size_t i = 0; i < argCount; i++)
    {
        lua_pushnumber(L, args[i]);
    }
    if (static_cast<lua_Status>(
            rive_lua_pcall_with_context(L, object, int(argCount) + 1, 1)) !=
        LUA_OK)
    {
        // Stack: [self, errorMessage]
        rive_lua_pop(L, 2);
        return false;
    }
    // Stack: [self, result]
    *outResult = static_cast<float>(lua_tonumber(L, -1));
    rive_lua_pop(L, 2);
    return true;
}

bool ScriptingVM::callBooleanMethod(ScriptedObject* object,
                                    int selfRef,
                                    const char* name)
{
    lua_State* L = m_state;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    lua_getfield(L, -1, name);
    // Stack: [self, field]
    lua_insert(L, -2); // Swap self and field
    // Stack: [field, self]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 1, 1)) !=
        LUA_OK)
    {
        // Stack: [status]
        rive_lua_pop(L, 1);
        return false;
    }
    bool result = lua_isboolean(L, -1) && lua_toboolean(L, -1);
    // Stack: [result]
    rive_lua_pop(L, 1);
    return result;
}

bool ScriptingVM::callPathEffectUpdate(ScriptedObject* object,
                                       int selfRef,
                                       const RawPath& sourcePath,
                                       const ShapePaint* shapePaint,
                                       RawPath* outPath)
{
    lua_State* L = m_state;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    lua_getfield(L, -1, "update");
    // Stack: [self, "update"]
    lua_pushvalue(L, -2);
    // Stack: [self, "update", self]
    lua_newrive<ScriptedPathData>(L, &sourcePath);
    // Stack: [self, "update", self, pathData]
    lua_newrive<ScriptedNode>(L,
                              nullptr,
                              shapePaint->parentTransformComponent());
    auto scriptedNode = lua_torive<ScriptedNode>(L, -1);
    scriptedNode->shapePaint(shapePaint);
    // Stack: [self, "update", self, pathData, node]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 3, 1)) !=
        LUA_OK)
    {
        // Stack: [self, status]
        rive_lua_pop(L, 2);
        return false;
    }
    // Stack: [self, outputPathData]
    // update() is script-authored, so it can return anything; a non-PathData
    // result means there's no geometry to contribute.
    auto scriptedPath = lua_topathdata(L, -1);
    if (scriptedPath == nullptr)
    {
        rive_lua_pop(L, 2);
        return false;
    }
    outPath->addPath(scriptedPath->rawPath);
    rive_lua_pop(L, 2);
    return true;
}

bool ScriptingVM::callDataConvert(ScriptedObject* object,
                                  int selfRef,
                                  const char* method,
                                  DataValue* input,
                                  ScriptDataResult* outResult)
{
    lua_State* L = m_state;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, method)) != LUA_TFUNCTION)
    {
        // Assumed for legacy files but not implemented; the caller passes the
        // value through unchanged (same as !dataConverts()).
        rive_lua_pop(L, 2); // non-function field + self
        return false;
    }
    // Stack: [self, field]
    lua_pushvalue(L, -2);
    // Stack: [self, field, self]
    if (input->is<DataValueNumber>())
    {
        lua_newrive<ScriptedDataValueNumber>(
            L,
            L,
            input->as<DataValueNumber>()->value());
    }
    else if (input->is<DataValueString>())
    {
        lua_newrive<ScriptedDataValueString>(
            L,
            L,
            input->as<DataValueString>()->value());
    }
    else if (input->is<DataValueBoolean>())
    {
        lua_newrive<ScriptedDataValueBoolean>(
            L,
            L,
            input->as<DataValueBoolean>()->value());
    }
    else if (input->is<DataValueColor>())
    {
        lua_newrive<ScriptedDataValueColor>(
            L,
            L,
            input->as<DataValueColor>()->value());
    }
    else
    {
        // Stack: [self, field, self]
        rive_lua_pop(L, 3);
        return true;
    }
    // Stack: [self, field, self, ScriptedData]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 2, 1)) ==
        LUA_OK)
    {
        // The script decides what convert() hands back. Anything that isn't
        // a DataValue (nil from a missing return, a raw Lua number, a table)
        // leaves the result kind as none, so the caller sees an empty value
        // instead of dereferencing null.
        auto result = lua_todatavalue(L, -1);
        if (result == nullptr)
        {
            // Stack: [self, result]
            rive_lua_pop(L, 2);
            return true;
        }
        if (result->isNumber())
        {
            outResult->kind = ScriptDataResult::Kind::number;
            outResult->number =
                result->dataValue()->as<DataValueNumber>()->value();
        }
        else if (result->isString())
        {
            outResult->kind = ScriptDataResult::Kind::string;
            outResult->string =
                result->dataValue()->as<DataValueString>()->value();
        }
        else if (result->isBoolean())
        {
            outResult->kind = ScriptDataResult::Kind::boolean;
            outResult->boolean =
                result->dataValue()->as<DataValueBoolean>()->value();
        }
        else if (result->isColor())
        {
            outResult->kind = ScriptDataResult::Kind::color;
            outResult->color =
                result->dataValue()->as<DataValueColor>()->value();
        }
    }
    // Stack: [self, status] or [self, result]
    rive_lua_pop(L, 2);
    return true;
}

void ScriptingVM::callListenerPerform(ScriptedObject* object,
                                      int selfRef,
                                      const ListenerInvocation& invocation)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    // Probe the fields directly (rather than gating on performs()/
    // performsAction(), which are assumed-present for legacy files):
    // performAction takes precedence over perform, matching prior behavior.
    if (static_cast<lua_Type>(lua_getfield(L, -1, "performAction")) ==
        LUA_TFUNCTION)
    {
        // Stack: [self, performAction]
        lua_pushvalue(L, -2);
        rive_lua_push_scripted_invocation(L, invocation);
        // Stack: [self, performAction, self, invocation]
        if (static_cast<lua_Status>(
                rive_lua_pcall_with_context(L, object, 2, 0)) != LUA_OK)
        {
            // Stack: [self, status]
            lua_pop(L, 1);
        }
        // Stack: [self]
    }
    else
    {
        lua_pop(L, 1); // non-function performAction field -> [self]
        if (static_cast<lua_Type>(lua_getfield(L, -1, "perform")) ==
            LUA_TFUNCTION)
        {
            // Stack: [self, perform]
            lua_pushvalue(L, -2);
            // Stack: [self, perform, self]
            rive_lua_push_pointer_arg_for_perform(L, invocation);
            // Stack: [self, perform, self, pointerEvent]
            if (static_cast<lua_Status>(
                    rive_lua_pcall_with_context(L, object, 2, 0)) != LUA_OK)
            {
                // Stack: [self, status]
                lua_pop(L, 1);
            }
            // Stack: [self]
        }
        else
        {
            lua_pop(L, 1); // non-function perform field -> [self]
        }
    }
    // Stack: [self]
    lua_pop(L, 1);
}

void ScriptingVM::callDraw(ScriptedObject* object,
                           int selfRef,
                           Renderer* renderer)
{
    lua_State* L = m_state;
    // Stack: []
    auto scriptedRenderer = lua_newrive<ScriptedRenderer>(L, renderer);
    // Stack: [scriptedRenderer]
    rive_lua_pushRef(L, selfRef);
    // Stack: [scriptedRenderer, self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, "draw")) == LUA_TFUNCTION)
    {
        // Stack: [scriptedRenderer, self, "draw"]
        lua_pushvalue(L, -2);
        // Stack: [scriptedRenderer, self, "draw", self]
        lua_pushvalue(L, -4);
        // Stack: [scriptedRenderer, self, "draw", self, scriptedRenderer]
        if (static_cast<lua_Status>(
                rive_lua_pcall_with_context(L, object, 2, 0)) != LUA_OK)
        {
            // Stack: [scriptedRenderer, self, status]
            rive_lua_pop(L, 1);
        }
    }
    else
    {
        // draw is assumed for legacy files but not implemented; no-op.
        rive_lua_pop(L, 1); // non-function field
    }
    scriptedRenderer->end();
    // Stack: [scriptedRenderer, self]
    rive_lua_pop(L, 2);
}

bool ScriptingVM::callGamepadEvent(ScriptedObject* object,
                                   int selfRef,
                                   const char* method,
                                   const ListenerInvocation& invocation)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    lua_getfield(L, -1, method);
    if (static_cast<lua_Type>(lua_type(L, -1)) != LUA_TFUNCTION)
    {
        rive_lua_pop(L, 2);
        return false;
    }
    lua_pushvalue(L, -2);
    if (const GamepadConnectedInvocation* c = invocation.asGamepadConnected())
    {
        lua_newrive<ScriptedGamepadConnected>(L, c->snapshot);
    }
    else if (const GamepadEventInvocation* e = invocation.asGamepadEvent())
    {
        lua_newrive<ScriptedGamepadEvent>(L, *e);
    }
    else if (const GamepadDisconnectedInvocation* d =
                 invocation.asGamepadDisconnected())
    {
        lua_newrive<ScriptedGamepadDisconnected>(L, d->deviceId);
    }
    else
    {
        rive_lua_pop(L, 3);
        return false;
    }
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 2, 0)) !=
        LUA_OK)
    {
        rive_lua_pop(L, 1);
    }
    rive_lua_pop(L, 1);
    return true;
}

bool ScriptingVM::callPointerEvent(ScriptedObject* object,
                                   int selfRef,
                                   const char* method,
                                   int pointerId,
                                   Vec2D localPosition,
                                   ListenerType hitType,
                                   float timeStamp,
                                   HitResult* outResult)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    if (static_cast<lua_Type>(lua_getfield(L, -1, method)) != LUA_TFUNCTION)
    {
        // The pointer handler is assumed present for legacy files (all-bits
        // default) but isn't actually implemented: the caller reports "not
        // hit" so the state machine keeps walking other hit targets.
        rive_lua_pop(L, 2);
        return false;
    }
    lua_pushvalue(L, -2);
    auto pointerEvent = lua_newrive<ScriptedPointerEvent>(L,
                                                          pointerId,
                                                          localPosition,
                                                          Vec2D(),
                                                          (int)hitType,
                                                          timeStamp);
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 2, 0)) !=
        LUA_OK)
    {
        fprintf(stderr, "%s failed\n", method);
        rive_lua_pop(L, 1);
    }
    *outResult = pointerEvent->m_hitResult;
    rive_lua_pop(L, 1);
    return true;
}

bool ScriptingVM::callKeyboardEvent(ScriptedObject* object,
                                    int selfRef,
                                    Key key,
                                    KeyModifiers modifiers,
                                    bool isPressed,
                                    bool isRepeat)
{
    lua_State* L = m_state;
    bool shouldStopPropagation = false;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, "keyboardEvent")) !=
        LUA_TFUNCTION)
    {
        // Assumed for legacy files but not implemented; no-op.
        rive_lua_pop(L, 2); // non-function field + self
        return shouldStopPropagation;
    }
    // Stack: [self, field]
    lua_pushvalue(L, -2);
    // Stack: [self, field, self]
    lua_newrive<ScriptedKeyboardInvocation>(L,
                                            key,
                                            modifiers,
                                            isPressed,
                                            isRepeat);
    // Stack: [self, field, self, keyEvent]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 2, 1)) !=
        LUA_OK)
    {
        fprintf(stderr, "%s failed\n", "keyboardEvent");
        // Stack: [self, status]
        rive_lua_pop(L, 1);
    }
    else
    {
        if (lua_isboolean(L, -1))
        {
            shouldStopPropagation = lua_toboolean(L, -1);
        }
        // Stack: [self, result]
        rive_lua_pop(L, 1);
    }
    // Stack: [self]
    rive_lua_pop(L, 1);
    return shouldStopPropagation;
}

bool ScriptingVM::callTextEvent(ScriptedObject* object,
                                int selfRef,
                                const std::string& text)
{
    lua_State* L = m_state;
    bool shouldStopPropagation = false;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, "textEvent")) !=
        LUA_TFUNCTION)
    {
        // Assumed for legacy files but not implemented; no-op.
        rive_lua_pop(L, 2); // non-function field + self
        return shouldStopPropagation;
    }
    // Stack: [self, field]
    lua_pushvalue(L, -2);
    // Stack: [self, field, self]
    lua_newrive<ScriptedTextInputInvocation>(L, text);
    // Stack: [self, field, self, textInvocation]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 2, 1)) !=
        LUA_OK)
    {
        fprintf(stderr, "%s failed\n", "textEvent");
        // Stack: [self, status]
        rive_lua_pop(L, 1);
    }
    else
    {
        if (lua_isboolean(L, -1))
        {
            shouldStopPropagation = lua_toboolean(L, -1);
        }
        // Stack: [self, result]
        rive_lua_pop(L, 1);
    }
    // Stack: [self]
    rive_lua_pop(L, 1);
    return shouldStopPropagation;
}

bool ScriptingVM::transitionManagesTo(int selfRef)
{
    lua_State* L = m_state;
    if (L == nullptr || selfRef == 0)
    {
        return true;
    }
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    lua_Type fieldType =
        static_cast<lua_Type>(lua_getfield(L, -1, "managesTo"));
    // Stack: [self, field]
    // Opt out only on an explicit boolean false; absent/nil/any other value
    // keeps the default (script composites both children).
    bool managesTo = !(fieldType == LUA_TBOOLEAN && !lua_toboolean(L, -1));
    rive_lua_pop(L, 2); // field + self
    return managesTo;
}

// Pushes a TransitionChild userdata for `child`, or nil when it carries no
// artboard. Returns the handle so the caller can invalidate it once the call
// returns, keeping the wrapper from outliving the frame's transforms.
static TransitionChild* pushTransitionChild(
    lua_State* L,
    const ScriptBackend::TransitionChildRef& child)
{
    if (child.artboard == nullptr)
    {
        lua_pushnil(L);
        return nullptr;
    }
    return lua_newrive<TransitionChild>(L, child.artboard, child.transform);
}

void ScriptingVM::callTransitionChanged(ScriptedObject* object,
                                        int selfRef,
                                        const TransitionChildRef& from,
                                        const TransitionChildRef& to,
                                        int direction)
{
    lua_State* L = m_state;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, "changed")) != LUA_TFUNCTION)
    {
        // changed is optional; nothing to notify.
        rive_lua_pop(L, 2); // non-function field + self
        return;
    }
    // Stack: [self, changed]
    lua_pushvalue(L, -2); // self (arg 1)
    // Stack: [self, changed, self]
    TransitionChild* fromHandle = pushTransitionChild(L, from);
    TransitionChild* toHandle = pushTransitionChild(L, to);
    lua_pushnumber(L, direction);
    // Stack: [self, changed, self, from, to, direction]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 4, 0)) !=
        LUA_OK)
    {
        // Stack: [self, status]
        rive_lua_pop(L, 1);
    }
    if (fromHandle != nullptr)
    {
        fromHandle->invalidate();
    }
    if (toHandle != nullptr)
    {
        toHandle->invalidate();
    }
    // Stack: [self]
    rive_lua_pop(L, 1);
}

void ScriptingVM::callTransitionDraw(ScriptedObject* object,
                                     int selfRef,
                                     Renderer* renderer,
                                     const TransitionChildRef& from,
                                     const TransitionChildRef& to)
{
    lua_State* L = m_state;
    // Stack: []
    auto scriptedRenderer = lua_newrive<ScriptedRenderer>(L, renderer);
    // Stack: [scriptedRenderer]
    TransitionChild* fromHandle = nullptr;
    TransitionChild* toHandle = nullptr;
    rive_lua_pushRef(L, selfRef);
    // Stack: [scriptedRenderer, self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, "draw")) == LUA_TFUNCTION)
    {
        // Stack: [scriptedRenderer, self, "draw"]
        lua_pushvalue(L, -2); // self (arg 1)
        // Stack: [scriptedRenderer, self, "draw", self]
        lua_pushvalue(L, -4); // scriptedRenderer (arg 2)
        // Stack: [scriptedRenderer, self, "draw", self, scriptedRenderer]
        fromHandle = pushTransitionChild(L, from);
        toHandle = pushTransitionChild(L, to);
        // Stack: [scriptedRenderer, self, "draw", self, sr, from, to]
        if (static_cast<lua_Status>(
                rive_lua_pcall_with_context(L, object, 4, 0)) != LUA_OK)
        {
            // Stack: [scriptedRenderer, self, status]
            rive_lua_pop(L, 1);
        }
    }
    else
    {
        // draw is assumed for the transition protocol but not implemented.
        rive_lua_pop(L, 1); // non-function field
    }
    if (fromHandle != nullptr)
    {
        fromHandle->invalidate();
    }
    if (toHandle != nullptr)
    {
        toHandle->invalidate();
    }
    scriptedRenderer->end();
    // Stack: [scriptedRenderer, self]
    rive_lua_pop(L, 2);
}

void ScriptingVM::callLayoutResize(ScriptedObject* object,
                                   int selfRef,
                                   Vec2D size)
{
    lua_State* L = m_state;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, "resize")) != LUA_TFUNCTION)
    {
        // Assumed for legacy files but not implemented; no-op.
        rive_lua_pop(L, 2); // non-function field + self
        return;
    }
    // Stack: [self, function]
    lua_pushvalue(L, -2);
    // Stack: [self, function, self]
    lua_pushvec2d(L, size);
    lua_pushnumber(L, displayScale());
    // Stack: [self, function, self, size, scale]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 3, 0)) !=
        LUA_OK)
    {
        // Stack: [self, status]
        fprintf(stderr,
                "resize failed: %s\n",
                lua_tostring(L, -1) ? lua_tostring(L, -1) : "?");
        rive_lua_pop(L, 1);
    }
    // Stack: [self]
    rive_lua_pop(L, 1);
}

bool ScriptingVM::callLayoutMeasure(ScriptedObject* object,
                                    int selfRef,
                                    Vec2D* outSize)
{
    lua_State* L = m_state;
    // Stack: []
    rive_lua_pushRef(L, selfRef);
    // Stack: [self]
    if (static_cast<lua_Type>(lua_getfield(L, -1, "measure")) != LUA_TFUNCTION)
    {
        // Assumed for legacy files but not implemented; report no
        // measurement (same as !measures()).
        rive_lua_pop(L, 2); // non-function field + self
        return false;
    }
    // Stack: [self, field]
    lua_pushvalue(L, -2);
    // Stack: [self, field, self]
    if (static_cast<lua_Status>(rive_lua_pcall_with_context(L, object, 1, 1)) !=
        LUA_OK)
    {
        fprintf(stderr, "measure failed\n");
    }
    else if (static_cast<lua_Type>(lua_type(L, -1)) != LUA_TVECTOR)
    {
        fprintf(stderr, "expected measure to return a Vec2D\n");
    }
    else
    {
        *outSize = *lua_tovec2d(L, -1);
    }
    // Stack: [self, status] or Stack: [self, result]
    rive_lua_pop(L, 2);
    return true;
}

void ScriptingVM::setInputBoolean(int selfRef, const char* name, bool value)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    lua_pushboolean(L, value);
    lua_setfield(L, -2, name);
    rive_lua_pop(L, 1);
}

void ScriptingVM::setInputNumber(int selfRef, const char* name, float value)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    lua_pushnumber(L, value);
    lua_setfield(L, -2, name);
    rive_lua_pop(L, 1);
}

void ScriptingVM::setInputUnsigned(int selfRef,
                                   const char* name,
                                   uint32_t value)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    lua_pushunsigned(L, value);
    lua_setfield(L, -2, name);
    rive_lua_pop(L, 1);
}

void ScriptingVM::setInputString(int selfRef,
                                 const char* name,
                                 const char* value)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    lua_pushstring(L, value);
    lua_setfield(L, -2, name);
    rive_lua_pop(L, 1);
}

void ScriptingVM::setInputArtboard(int selfRef,
                                   const char* name,
                                   ScriptedObject* object,
                                   Artboard* artboard)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    auto artboardInstance = artboard->instance();
    artboardInstance->frameOrigin(false);
    lua_newrive<ScriptedArtboard>(L,
                                  L,
                                  object->scriptAsset()->file(),
                                  std::move(artboardInstance),
                                  nullptr,
                                  object->dataContext());
    lua_setfield(L, -2, name);
    rive_lua_pop(L, 1);
}

void ScriptingVM::setInputViewModel(int selfRef,
                                    const char* name,
                                    ViewModelInstanceValue* value)
{
    lua_State* L = m_state;
    rive_lua_pushRef(L, selfRef);
    switch (value->coreType())
    {
        case ViewModelInstanceViewModelBase::typeKey:
        {
            auto viewModel = value->as<ViewModelInstanceViewModel>();
            auto vmi = viewModel->referenceViewModelInstance();
            if (vmi == nullptr)
            {
                fprintf(stderr,
                        "setInputViewModel - passed in a "
                        "ViewModelInstanceViewModel with no associated "
                        "ViewModelInstance.\n");
                rive_lua_pop(L, 1);
                return;
            }

            lua_newrive<ScriptedViewModel>(L,
                                           L,
                                           ref_rcp(vmi->viewModel()),
                                           vmi);
            break;
        }
        default:
            // Nothing pushed; leave self untouched.
            rive_lua_pop(L, 1);
            return;
    }
    lua_setfield(L, -2, name);
    rive_lua_pop(L, 1);
}

#endif
