#ifdef WITH_RIVE_SCRIPTING
#ifndef _RIVE_SCRIPTING_VM_HPP_
#define _RIVE_SCRIPTING_VM_HPP_

#include "rive/refcnt.hpp"
#include "rive/scripted/script_backend.hpp"
#include "rive/span.hpp"
#include <memory>
#include <unordered_set>

struct lua_State;

namespace rive
{
class ModuleDetails;
class ScriptingContext;
class ScriptedObject;

class ScriptingVM : public RefCnt<ScriptingVM>, public ScriptBackend
{
public:
    // Creates a ScriptingVM that owns both the lua_State and the context.
    explicit ScriptingVM(std::unique_ptr<ScriptingContext> context);

    ~ScriptingVM();

    // Closes the lua_State synchronously and runs all userdata finalizers.
    // Idempotent. Called from ~ScriptingVM but exposed so call sites that
    // need teardown to be observable (e.g. between editor file swaps) can
    // force it.
    void closeLuaState();

    ScriptingContext* context() { return m_ownedContext.get(); }
    lua_State* state() const { return m_state; }

    // ScriptBackend, implemented in src/lua/lua_script_backend.cpp.
    bool valid() const override { return m_state != nullptr; }
    void releaseRef(int ref) override;
    int resolveGeneratorRef(int ref) const override;
    int instantiate(int generatorRef,
                    ScriptedObject* object,
                    int* outContextRef,
                    ScriptedContext** outContextPtr) override;
    InitResult callUserInit(ScriptedObject* object,
                            int selfRef,
                            int contextRef) override;
    bool callAdvance(ScriptedObject* object,
                     int selfRef,
                     float elapsedSeconds) override;
    void callUpdate(ScriptedObject* object, int selfRef) override;
    void callTrigger(ScriptedObject* object,
                     int selfRef,
                     const char* name) override;
    bool callNumberMethod(ScriptedObject* object,
                          int selfRef,
                          const char* name,
                          const float* args,
                          size_t argCount,
                          float* outResult) override;
    bool callBooleanMethod(ScriptedObject* object,
                           int selfRef,
                           const char* name) override;
    bool callPathEffectUpdate(ScriptedObject* object,
                              int selfRef,
                              const RawPath& sourcePath,
                              const ShapePaint* shapePaint,
                              RawPath* outPath) override;
    bool callDataConvert(ScriptedObject* object,
                         int selfRef,
                         const char* method,
                         DataValue* input,
                         ScriptDataResult* outResult) override;
    void callListenerPerform(ScriptedObject* object,
                             int selfRef,
                             const ListenerInvocation& invocation) override;
    void callDraw(ScriptedObject* object,
                  int selfRef,
                  Renderer* renderer) override;
    bool callGamepadEvent(ScriptedObject* object,
                          int selfRef,
                          const char* method,
                          const ListenerInvocation& invocation) override;
    bool callPointerEvent(ScriptedObject* object,
                          int selfRef,
                          const char* method,
                          int pointerId,
                          Vec2D localPosition,
                          ListenerType hitType,
                          float timeStamp,
                          HitResult* outResult) override;
    bool callKeyboardEvent(ScriptedObject* object,
                           int selfRef,
                           Key key,
                           KeyModifiers modifiers,
                           bool isPressed,
                           bool isRepeat) override;
    bool callTextEvent(ScriptedObject* object,
                       int selfRef,
                       const std::string& text) override;
    bool transitionManagesTo(int selfRef) override;
    void callTransitionChanged(ScriptedObject* object,
                               int selfRef,
                               const TransitionChildRef& from,
                               const TransitionChildRef& to,
                               int direction) override;
    void callTransitionDraw(ScriptedObject* object,
                            int selfRef,
                            Renderer* renderer,
                            const TransitionChildRef& from,
                            const TransitionChildRef& to) override;
    void callLayoutResize(ScriptedObject* object,
                          int selfRef,
                          Vec2D size) override;
    bool callLayoutMeasure(ScriptedObject* object,
                           int selfRef,
                           Vec2D* outSize) override;
    void setInputBoolean(int selfRef, const char* name, bool value) override;
    void setInputNumber(int selfRef, const char* name, float value) override;
    void setInputUnsigned(int selfRef,
                          const char* name,
                          uint32_t value) override;
    void setInputString(int selfRef,
                        const char* name,
                        const char* value) override;
    void setInputArtboard(int selfRef,
                          const char* name,
                          ScriptedObject* object,
                          Artboard* artboard) override;
    void setInputViewModel(int selfRef,
                           const char* name,
                           ViewModelInstanceValue* value) override;

    // Replaces the owned context with a new one. The old context is deleted
    // and the new context is owned by this VM. Also updates lua thread data.
    void replaceContext(std::unique_ptr<ScriptingContext> newContext);

    static void init(lua_State* state, ScriptingContext* context);

    // Add a module to be registered later via performRegistration()
    void addModule(ModuleDetails* moduleDetails);

    // Perform registration of all added modules, handling dependencies and
    // retries
    void performRegistration();

    // name is the require cache key, chunkname the trace label baked into
    // the bytecode, defaulting to name.
    static bool registerModule(lua_State* state,
                               const char* name,
                               Span<uint8_t> bytecode,
                               const char* chunkname = nullptr);
    static void unregisterModule(lua_State* state, const char* name);
    bool registerModule(const char* name, Span<uint8_t> bytecode);
    void unregisterModule(const char* name);

    static bool registerScript(lua_State* state,
                               const char* name,
                               Span<uint8_t> bytecode,
                               const char* chunkname = nullptr);

    bool registerScript(const char* name, Span<uint8_t> bytecode);

    // Loads bytecode into an unexecuted sandboxed thread pushed onto the
    // stack. name is the chunkname baked into the proto.
    static bool loadModule(lua_State* state,
                           const char* name,
                           Span<uint8_t> bytecode);

    // Executes a thread from loadModule and registers utility modules under
    // name. The result replaces the thread on the stack.
    static bool executeModule(lua_State* state,
                              const char* name,
                              bool isUtility,
                              const char* chunkname = nullptr);

    static void dumpStack(lua_State* state);

private:
    lua_State* m_state;
    std::unique_ptr<ScriptingContext> m_ownedContext;
};

} // namespace rive
#endif
#endif
