#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/viewmodel/viewmodel_property_asset_image.hpp"
#include "rive/viewmodel/viewmodel_property_boolean.hpp"
#include "rive/viewmodel/viewmodel_property_color.hpp"
#include "rive/viewmodel/viewmodel_property_enum.hpp"
#include "rive/viewmodel/viewmodel_property_number.hpp"
#include "rive/viewmodel/viewmodel_property_string.hpp"
#include "rive/viewmodel/viewmodel_property_trigger.hpp"
#include "rive/viewmodel/viewmodel_property_list.hpp"
#include "rive/viewmodel/viewmodel_property_symbol_list_index.hpp"
#include "rive/viewmodel/viewmodel_property_viewmodel.hpp"
#include "rive/viewmodel/viewmodel_instance_asset_image.hpp"
#include "rive/viewmodel/viewmodel_property_asset_font.hpp"
#include "rive/viewmodel/viewmodel_instance_asset_font.hpp"
#include "rive/viewmodel/viewmodel_property_asset_blob.hpp"
#include "rive/viewmodel/viewmodel_instance_asset_blob.hpp"
#include "rive/viewmodel/viewmodel_instance_list.hpp"
#include "rive/viewmodel/viewmodel_instance_enum.hpp"
#include "rive/viewmodel/viewmodel_instance_list_item.hpp"
#include "rive/viewmodel/viewmodel_instance_symbol_list_index.hpp"
#include "rive/scripted/scripted_object.hpp"
#include "rive/assets/image_asset.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/file.hpp"
#ifdef WITH_RIVE_TOOLS
#include "rive/viewmodel/viewmodel.hpp"
#include "rive/viewmodel/viewmodel_instance.hpp"
#endif

#include <math.h>

using namespace rive;

static ScriptingContext* scriptingContext(lua_State* L)
{
    return static_cast<ScriptingContext*>(lua_getthreaddata(L));
}

static void pushViewModelInstanceValue(lua_State* L,
                                       ViewModelInstanceValue* propValue)
{
    switch (propValue->coreType())
    {
        case ViewModelInstanceNumberBase::typeKey:
            lua_newrive<ScriptedPropertyNumber>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceNumber>()));
            break;
        case ViewModelInstanceTriggerBase::typeKey:
            lua_newrive<ScriptedPropertyTrigger>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceTrigger>()));
            break;
        case ViewModelInstanceListBase::typeKey:
            lua_newrive<ScriptedPropertyList>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceList>()));
            break;
        case ViewModelInstanceColorBase::typeKey:
            lua_newrive<ScriptedPropertyColor>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceColor>()));
            break;
        case ViewModelInstanceStringBase::typeKey:
            lua_newrive<ScriptedPropertyString>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceString>()));
            break;
        case ViewModelInstanceBooleanBase::typeKey:
            lua_newrive<ScriptedPropertyBoolean>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceBoolean>()));
            break;
        case ViewModelInstanceEnumBase::typeKey:
            lua_newrive<ScriptedPropertyEnum>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceEnum>()));
            break;
        case ViewModelInstanceViewModelBase::typeKey:
        {
            // The wrapper needs the referenced view model, not the owner's, so
            // instance() mints the nested type.
            auto vmValue = propValue->as<ViewModelInstanceViewModel>();
            auto reference = vmValue->referenceViewModelInstance();
            lua_newrive<ScriptedPropertyViewModel>(
                L,
                L,
                reference != nullptr ? ref_rcp(reference->viewModel())
                                     : nullptr,
                ref_rcp(vmValue));
            break;
        }
        case ViewModelInstanceSymbolListIndexBase::typeKey:
        {

            auto listIndexProp =
                propValue->as<ViewModelInstanceSymbolListIndex>();
            lua_pushinteger(L, listIndexProp->propertyValue());
            break;
        }
        case ViewModelInstanceAssetImageBase::typeKey:
        {
            lua_newrive<ScriptedPropertyImage>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceAssetImage>()));
            break;
        }
        case ViewModelInstanceAssetFontBase::typeKey:
        {
            lua_newrive<ScriptedPropertyFont>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceAssetFont>()));
            break;
        }
        case ViewModelInstanceAssetBlobBase::typeKey:
        {
            lua_newrive<ScriptedPropertyBlob>(
                L,
                L,
                ref_rcp(propValue->as<ViewModelInstanceAssetBlob>()));
            break;
        }
        default:
            lua_pushnil(L);
            break;
    }
}

// int ScriptedPropertyViewModel::pushValueOfType(const char* name, int
// coreType)
// {
//     auto vmi = m_instanceValue->referenceViewModelInstance();
//     if (!vmi)
//     {
//         lua_pushnil(m_state);
//     }
//     else
//     {
//         auto propValue = vmi->propertyValue(name);
//         if (propValue->coreType() != coreType)
//         {
//             lua_pushnil(m_state);
//         }
//         else
//         {
//             pushViewModelInstanceValue(m_state, propValue);
//         }
//     }
//     return 1;
// }

ScriptedProperty::~ScriptedProperty() { dispose(); }

ScriptedPropertyViewModel::~ScriptedPropertyViewModel() { dispose(); }

void ScriptedProperty::clearCachedValueRef()
{
    if (m_cachedValueRef != 0)
    {
        lua_unref(m_state, m_cachedValueRef);
        m_cachedValueRef = 0;
    }
}

void ScriptedProperty::clearListeners()
{
    for (auto itr = m_listeners.begin(); itr != m_listeners.end(); ++itr)
    {
        const ScriptedListener& listener = *itr;
        lua_unref(m_state, listener.function);
        if (listener.userdata)
        {
            lua_unref(m_state, listener.userdata);
        }
        lua_unref(m_state, listener.propertySelfRef);
    }
    m_listeners.clear();
}

ScriptedProperty::ScriptedProperty(lua_State* L,
                                   rcp<ViewModelInstanceValue> value) :
    m_state(L), m_instanceValue(std::move(value))
{
    if (m_instanceValue != nullptr)
    {
        m_instanceValue->addDelegate(this);
        // See m_owningInstance: the value's back-pointer is raw, so without
        // this the view model can die under a script that is still holding one
        // of its properties.
        m_owningInstance = ref_rcp(m_instanceValue->viewModelInstance());
    }

    auto context = scriptingContext(L);
    if (context != nullptr)
    {
        m_owner = context->currentScriptedObject();
        if (m_owner != nullptr)
        {
            m_owner->addTrackedScriptedProperty(this);
        }
#ifdef WITH_RIVE_TOOLS
        else
        {
            context->trackOrphanScriptedProperty(this);
            m_orphanContext = context;
            m_orphanOwnerTag = context->orphanOwnerTag();
        }
#endif
    }
}

void ScriptedProperty::dispose()
{
    if (m_disposed)
    {
        return;
    }
    m_disposed = true;

    if (m_owner != nullptr)
    {
        m_owner->removeTrackedScriptedProperty(this);
        m_owner = nullptr;
    }
#ifdef WITH_RIVE_TOOLS
    if (m_orphanContext != nullptr)
    {
        m_orphanContext->untrackOrphanScriptedProperty(this);
        m_orphanContext = nullptr;
    }
#endif

    if (m_instanceValue != nullptr)
    {
        m_instanceValue->removeDelegate(this);
        m_instanceValue = nullptr;
    }
    m_owningInstance = nullptr;

    clearCachedValueRef();
    clearListeners();
}

void ScriptedProperty::valueChanged()
{
    clearCachedValueRef();
    if (m_listeners.empty())
    {
        return;
    }
    if (!lua_checkstack(m_state, (int)(m_listeners.size() * 2 + LUA_MINSTACK)))
    {
        return;
    }
    // This works because we don't actually call as we go (or we could
    // invalidate listeners if a callback registers a new or removes a
    // listener). Instead, we build up the call stack and then call for each
    // callback on the stack.
    for (auto itr = m_listeners.rbegin(); itr != m_listeners.rend(); itr++)
    {
        const ScriptedListener& listener = *itr;
        lua_rawgeti(m_state, LUA_REGISTRYINDEX, listener.function);
        if (listener.userdata)
        {
            lua_rawgeti(m_state, LUA_REGISTRYINDEX, listener.userdata);
        }
        else
        {
            // push nil so we have a constant number of args per call
            lua_pushnil(m_state);
        }
    }
    size_t calls = m_listeners.size();
    for (size_t i = 0; i < calls; i++)
    {
        lua_pcall(m_state, 1, 0, 0);
    }
}

int ScriptedProperty::addListener()
{
    if (lua_isfunction(m_state, 2))
    {
        lua_pushvalue(m_state, 1);
        int propertySelfRef = lua_ref(m_state, -1);
        lua_pop(m_state, 1);
        int callbackRef = lua_ref(m_state, 2);
        m_listeners.push_back({callbackRef, 0, propertySelfRef});
        return 0;
    }
    else if (lua_isfunction(m_state, 3))
    {
        lua_pushvalue(m_state, 1);
        int propertySelfRef = lua_ref(m_state, -1);
        lua_pop(m_state, 1);
        int userdataRef = lua_ref(m_state, 2);
        int callbackRef = lua_ref(m_state, 3);
        m_listeners.push_back({callbackRef, userdataRef, propertySelfRef});
        return 0;
    }

    luaL_typeerrorL(m_state, 2, lua_typename(m_state, LUA_TFUNCTION));
    return 0;
}

int ScriptedProperty::removeListener()
{
    int checkIndex;
    if (lua_isfunction(m_state, 2))
    {
        checkIndex = 2;
    }
    else if (lua_isfunction(m_state, 3))
    {
        checkIndex = 3;
    }
    else
    {
        luaL_typeerrorL(m_state, 2, lua_typename(m_state, LUA_TFUNCTION));
    }

    for (auto itr = m_listeners.begin(); itr != m_listeners.end();)
    {
        const ScriptedListener& listener = *itr;
        lua_rawgeti(m_state, LUA_REGISTRYINDEX, listener.function);
        if (lua_rawequal(m_state, -1, checkIndex))
        {
            lua_unref(m_state, listener.function);
            if (listener.userdata)
            {
                lua_unref(m_state, listener.userdata);
            }
            lua_unref(m_state, listener.propertySelfRef);
            itr = m_listeners.erase(itr);
        }
        else
        {
            ++itr;
        }
        lua_pop(m_state, 1);
    }
    return 0;
}

ScriptedPropertyViewModel::ScriptedPropertyViewModel(
    lua_State* L,
    rcp<ViewModel> viewModel,
    rcp<ViewModelInstanceViewModel> value) :
    ScriptedProperty(L, std::move(value)), m_viewModel(std::move(viewModel))
{}

void ScriptedPropertyViewModel::setValue(ScriptedViewModel* scriptedViewModel)
{
    if (m_instanceValue != nullptr &&
        m_instanceValue->is<ViewModelInstanceViewModel>())
    {
        auto vmValue = m_instanceValue->as<ViewModelInstanceViewModel>();
        auto parentViewModelInstance = vmValue->parentViewModelInstance();
        auto viewModelInstance = scriptedViewModel->mutableViewModelInstance();
        // replaceViewModelByProperty notifies this property's value-dependents
        // (including this wrapper and any siblings sharing the property) so
        // cached Lua-side wrappers are moved onto the new instance.
        parentViewModelInstance->replaceViewModelByProperty(
            vmValue,
            rcp<ViewModelInstance>(viewModelInstance));
    }
}

void ScriptedPropertyViewModel::dispose()
{
    if (m_instanceValue)
    {
        m_instanceValue->removeDependent(this);
    }
    clearRef();
    ScriptedProperty::dispose();
}

void ScriptedPropertyViewModel::clearRef()
{

    if (m_valueRef != 0)
    {
        lua_unref(m_state, m_valueRef);
        m_valueRef = 0;
    }
}

ScriptedViewModel::ScriptedViewModel(lua_State* L,
                                     rcp<ViewModel> viewModel,
                                     rcp<ViewModelInstance> viewModelInstance) :
    m_state(L), m_viewModel(viewModel), m_viewModelInstance(viewModelInstance)
{
    // Register the instance so detached ones (no parents) get advanced at the
    // end of each frame. Tracking is keyed to owner lifetime, so the instance
    // stays tracked while any owner (this wrapper, a scripted artboard) is
    // alive. Store the context so unregistration in the destructor does not
    // depend on lua_getthreaddata during Lua finalization.
    m_scriptingContext = scriptingContext(L);
    if (m_scriptingContext != nullptr)
    {
        m_scriptingContext->trackViewModelInstance(m_viewModelInstance);
    }
}

ScriptedViewModel::~ScriptedViewModel()
{
    if (m_scriptingContext != nullptr)
    {
        m_scriptingContext->untrackViewModelInstance(m_viewModelInstance.get());
    }
    for (auto itr : m_propertyRefs)
    {
        lua_unref(m_state, itr.second);
    }
}

int ScriptedViewModel::instance(lua_State* L)
{
    if (m_viewModel)
    {

        int nargs = lua_gettop(L);
        if (nargs == 2)
        {
            if (lua_isnoneornil(L, -1) || !lua_isstring(L, -1))
            {
                auto instance = m_viewModel->createInstance();
                lua_newrive<ScriptedViewModel>(L, L, m_viewModel, instance);
            }
            else
            {
                const char* instanceName = lua_tostring(L, -1);
                auto instance = m_viewModel->createFromInstance(instanceName);
                if (!instance)
                {
                    instance = m_viewModel->createInstance();
                }
                lua_newrive<ScriptedViewModel>(L, L, m_viewModel, instance);
            }
        }
        else
        {
            auto instance = m_viewModel->createInstance();
            lua_newrive<ScriptedViewModel>(L, L, m_viewModel, instance);
        }
    }
    else
    {
        lua_pushnil(L);
    }
    return 1;
}

#ifdef WITH_RIVE_TOOLS
static ScriptedProperty* scriptedPropertyOrNull(lua_State* L, int idx)
{
    if (!lua_isuserdata(L, idx))
    {
        return nullptr;
    }
    switch (lua_userdatatag(L, idx))
    {
        case ScriptedPropertyNumber::luaTag:
        case ScriptedPropertyTrigger::luaTag:
        case ScriptedPropertyList::luaTag:
        case ScriptedPropertyColor::luaTag:
        case ScriptedPropertyString::luaTag:
        case ScriptedPropertyBoolean::luaTag:
        case ScriptedPropertyEnum::luaTag:
        case ScriptedPropertyImage::luaTag:
        case ScriptedPropertyFont::luaTag:
        case ScriptedPropertyBlob::luaTag:
            return (ScriptedProperty*)lua_touserdata(L, idx);
        case ScriptedPropertyViewModel::luaTag:
            // Two bases, so the upcast goes through the concrete type rather
            // than reinterpreting the allocation. Leaving it out handed back
            // a disposed nested view model instead of re-minting it.
            return static_cast<ScriptedPropertyViewModel*>(
                lua_touserdata(L, idx));
        default:
            return nullptr;
    }
}
#endif

int ScriptedViewModel::pushValue(const char* name, int coreType)
{
    auto itr = m_propertyRefs.find(name);
    if (itr != m_propertyRefs.end())
    {
        lua_rawgeti(m_state, LUA_REGISTRYINDEX, itr->second);
#ifdef WITH_RIVE_TOOLS
        // A wrapper with no owner is swept by File teardown / VM swap, which
        // keeps this lua_State alive -- leaving this view model (cached on a
        // long-lived artboard or self) holding a dead wrapper. Disposal is
        // terminal, so re-mint rather than hand the dead one back. Owned
        // wrappers die with the object that owns them, together with this.
        ScriptedProperty* cached = scriptedPropertyOrNull(m_state, -1);
        if (cached != nullptr && cached->disposed())
        {
            lua_pop(m_state, 1);
            lua_unref(m_state, itr->second);
            m_propertyRefs.erase(itr);
        }
        else
        {
            return 1;
        }
#else
        return 1;
#endif
    }
    // To be fully typesafe at runtime we should check the property in the
    // viewmodel and make sure the one in the value matches the same type or
    // return a default based on the type of the viewmodel, but this incurs
    // extra performance and since our type system at edit-time lets the user be
    // intentional, for now we runtime error if the type is un-expected and we
    // optimize for the best case.

    auto vmi = m_viewModelInstance;
    if (!vmi)
    {
        // Get type from viewmodel if we have one and user didn't request a type
        // dynamically.
        if (coreType != 0 || !m_viewModel)
        {
            lua_pushnil(m_state);
        }
        else
        {
            auto prop = m_viewModel->property(name);
            switch (prop->coreType())
            {
                case ViewModelPropertyNumberBase::typeKey:
                    lua_newrive<ScriptedPropertyNumber>(m_state,
                                                        m_state,
                                                        nullptr);
                    break;
                case ViewModelPropertyTriggerBase::typeKey:
                    lua_newrive<ScriptedPropertyTrigger>(m_state,
                                                         m_state,
                                                         nullptr);
                    break;
                case ViewModelPropertyListBase::typeKey:
                    lua_newrive<ScriptedPropertyList>(m_state,
                                                      m_state,
                                                      nullptr);
                    break;
                case ViewModelPropertyColorBase::typeKey:
                    lua_newrive<ScriptedPropertyColor>(m_state,
                                                       m_state,
                                                       nullptr);
                    break;
                case ViewModelPropertyStringBase::typeKey:
                    lua_newrive<ScriptedPropertyString>(m_state,
                                                        m_state,
                                                        nullptr);
                    break;
                case ViewModelPropertyBooleanBase::typeKey:
                    lua_newrive<ScriptedPropertyBoolean>(m_state,
                                                         m_state,
                                                         nullptr);
                    break;
                case ViewModelPropertyEnumBase::typeKey:
                    lua_newrive<ScriptedPropertyEnum>(m_state,
                                                      m_state,
                                                      nullptr);
                    break;
                case ViewModelPropertyViewModelBase::typeKey:
                    lua_newrive<ScriptedPropertyViewModel>(m_state,
                                                           m_state,
                                                           nullptr,
                                                           nullptr);
                    break;
                case ViewModelPropertyAssetImageBase::typeKey:
                    lua_newrive<ScriptedPropertyImage>(m_state,
                                                       m_state,
                                                       nullptr);
                    break;
                case ViewModelPropertyAssetFontBase::typeKey:
                    lua_newrive<ScriptedPropertyFont>(m_state,
                                                      m_state,
                                                      nullptr);
                    break;
                case ViewModelPropertyAssetBlobBase::typeKey:
                    lua_newrive<ScriptedPropertyBlob>(m_state,
                                                      m_state,
                                                      nullptr);
                    break;
                case ViewModelPropertySymbolListIndexBase::typeKey:
                    lua_pushinteger(m_state, 1);
                    break;
            }
        }
    }
    else
    {
        auto propValue = vmi->propertyValue(name);
        if (propValue == nullptr ||
            (coreType != 0 && propValue->coreType() != coreType))
        {
            lua_pushnil(m_state);
        }
        else
        {
            pushViewModelInstanceValue(m_state, propValue);
        }
    }
    m_propertyRefs[name] = lua_ref(m_state, -1);
    return 1;
}

int ScriptedViewModel::pushIndex()
{
    auto prop = m_viewModelInstance->propertyValue(SymbolType::itemIndex);
    if (prop && prop->is<ViewModelInstanceSymbolListIndex>())
    {
        lua_pushinteger(
            m_state,
            prop->as<ViewModelInstanceSymbolListIndex>()->propertyValue());
    }
    else
    {
        lua_pushinteger(m_state, -1);
    }
    return 1;
}

int ScriptedPropertyViewModel::pushValue()
{
    if (m_valueRef != 0)
    {
        lua_rawgeti(m_state, LUA_REGISTRYINDEX, m_valueRef);
        return 1;
    }
    if (m_instanceValue)
    {
        m_instanceValue->addDependent(this);
        // Derive the view model from the current reference; the creation-time
        // one goes stale when the reference binds or swaps after a relink.
        auto reference = m_instanceValue->as<ViewModelInstanceViewModel>()
                             ->referenceViewModelInstance();
        lua_newrive<ScriptedViewModel>(m_state,
                                       m_state,
                                       reference != nullptr
                                           ? ref_rcp(reference->viewModel())
                                           : m_viewModel,
                                       reference);
    }
    else
    {
        // Push nil or push an empty model ref? For now empty/with def values.
        lua_newrive<ScriptedViewModel>(m_state, m_state, m_viewModel, nullptr);
    }
    m_valueRef = lua_ref(m_state, -1);
    return 1;
}

// The reference moved, so the cached wrapper describes a view model this
// property no longer points at. Drop it; the next read mints one for the new
// reference. Wrappers a script already resolved keep working against the
// instance they came from, which stays alive through m_owningInstance: a
// swapped-in view model is a different set of properties, and a script asks
// for those by resolving them again.
void ScriptedPropertyViewModel::relinkDataBind() { clearRef(); }

static int property_vm_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto vmProp = lua_torive<ScriptedPropertyViewModel>(L, 1);
    assert(vmProp->state() == L);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            return vmProp->pushValue();
        default:
            return 0;
    }
}

static int property_vm_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto scriptedPropertyViewModel =
        lua_torive<ScriptedPropertyViewModel>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
        {
            auto vm = lua_torive<ScriptedViewModel>(L, 3);
            scriptedPropertyViewModel->setValue(vm);
            break;
        }
        default:
            return 0;
    }

    return 0;
}

static int vm_index(lua_State* L)
{
    auto vm = lua_torive<ScriptedViewModel>(L, 1);
    size_t namelen = 0;
    const char* name = luaL_checklstring(L, 2, &namelen);
    assert(vm->state() == L);
    return vm->pushValue(name);
}

static int property_namecall_atom(lua_State* L,
                                  ScriptedProperty* property,
                                  int atom,
                                  bool& error)
{
    switch (atom)
    {
        case (int)LuaAtoms::addListener:
        {
            assert(property->state() == L);
            return property->addListener();
        }
        case (int)LuaAtoms::removeListener:
        {
            assert(property->state() == L);
            return property->removeListener();
        }
        case (int)LuaAtoms::fire:
        {
            auto value = property->instanceValue();
            if (value != nullptr && value->is<ViewModelInstanceTrigger>())
            {
                value->as<ViewModelInstanceTrigger>()->trigger();
            }
            return 0;
        }
        case (int)LuaAtoms::push:
        {
            auto scriptedViewModel = lua_torive<ScriptedViewModel>(L, 2);
            auto vmi = scriptedViewModel->viewModelInstance();
            auto copy = ref_rcp(vmi.get());
            auto list = property->instanceValue()->as<ViewModelInstanceList>();
            auto listItem = make_rcp<ViewModelInstanceListItem>();

            listItem->viewModelInstance(copy);
            list->addItem(listItem);
            return 0;
        }
        case (int)LuaAtoms::pop:
        {
            auto list = property->instanceValue()->as<ViewModelInstanceList>();
            auto listItem = list->pop();
            if (listItem)
            {
                auto vmi = listItem->viewModelInstance();
                if (vmi)
                {
                    lua_newrive<ScriptedViewModel>(L,
                                                   L,
                                                   ref_rcp(vmi->viewModel()),
                                                   vmi);
                    return 1;
                }
            }
            return 0;
        }
        case (int)LuaAtoms::swap:
        {
            auto list = property->instanceValue()->as<ViewModelInstanceList>();
            auto index1 = lua_tounsigned(L, 2);
            auto index2 = lua_tounsigned(L, 3);
            list->swap(index1 - 1, index2 - 1);
            return 0;
        }
        case (int)LuaAtoms::shift:
        {
            auto list = property->instanceValue()->as<ViewModelInstanceList>();
            auto listItem = list->shift();
            if (listItem)
            {
                auto vmi = listItem->viewModelInstance();
                if (vmi)
                {
                    lua_newrive<ScriptedViewModel>(L,
                                                   L,
                                                   ref_rcp(vmi->viewModel()),
                                                   vmi);
                    return 1;
                }
            }
            return 0;
        }
        case (int)LuaAtoms::clear:
        {
            auto list = property->instanceValue()->as<ViewModelInstanceList>();
            list->removeAllItems();
            return 0;
        }

        case (int)LuaAtoms::insert:
        {
            auto scriptedViewModel = lua_torive<ScriptedViewModel>(L, 2);
            auto index = lua_tounsigned(L, 3);
            auto vmi = scriptedViewModel->viewModelInstance();
            auto copy = ref_rcp(vmi.get());
            auto list = property->instanceValue()->as<ViewModelInstanceList>();
            auto listItem = make_rcp<ViewModelInstanceListItem>();

            listItem->viewModelInstance(copy);
            list->addItemAt(listItem, index - 1);
            return 0;
        }

        case (int)LuaAtoms::remove:
        {
            auto list = property->instanceValue()->as<ViewModelInstanceList>();
            auto* vmUser = static_cast<ScriptedViewModel*>(
                lua_touserdatatagged(L, 2, ScriptedViewModel::luaTag));
            if (vmUser != nullptr)
            {
                auto vmi = vmUser->viewModelInstance();
                if (vmi)
                {
                    for (const auto& item : list->listItems())
                    {
                        if (item->viewModelInstance() == vmi)
                        {
                            list->removeItem(item);
                            break;
                        }
                    }
                }
            }
            return 0;
        }

        case (int)LuaAtoms::removeAt:
        {
            auto list = property->instanceValue()->as<ViewModelInstanceList>();
            const lua_Integer luaIndex = luaL_checkinteger(L, 2);
            const size_t count = list->listItems().size();
            if (luaIndex < 1 ||
                static_cast<uint64_t>(luaIndex) > static_cast<uint64_t>(count))
            {
                luaL_error(L, "removeAt index out of range");
            }
            list->removeItem(static_cast<int>(luaIndex - 1));
            return 0;
        }

        case (int)LuaAtoms::removeAllOf:
        {
            auto list = property->instanceValue()->as<ViewModelInstanceList>();
            auto* vmUser = static_cast<ScriptedViewModel*>(
                lua_touserdatatagged(L, 2, ScriptedViewModel::luaTag));
            if (vmUser != nullptr)
            {
                auto vmi = vmUser->viewModelInstance();
                if (vmi)
                {
                    list->removeAllItemsWithViewModelInstance(vmi.get());
                }
            }
            return 0;
        }

        case (int)LuaAtoms::values:
        {
            auto viewModelInstanceEnum =
                property->instanceValue()->as<ViewModelInstanceValue>();
            DataEnum* dataEnum = nullptr;
            auto viewModelPropertyEnum =
                viewModelInstanceEnum->viewModelProperty()
                    ->as<ViewModelPropertyEnum>();
            if (viewModelPropertyEnum)
            {
                dataEnum = viewModelPropertyEnum->dataEnum();
            }
            lua_newrive<ScriptedEnumValues>(L, L, dataEnum);

            return 1;
        }
    }
    error = true;
    return 0;
}

static int vm_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        auto vm = lua_torive<ScriptedViewModel>(L, 1);
        switch (atom)
        {
            case (int)LuaAtoms::getNumber:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name,
                                     ViewModelInstanceNumberBase::typeKey);
            }
            case (int)LuaAtoms::getTrigger:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name,
                                     ViewModelInstanceTriggerBase::typeKey);
            }
            case (int)LuaAtoms::getString:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name,
                                     ViewModelInstanceStringBase::typeKey);
            }
            case (int)LuaAtoms::getBoolean:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name,
                                     ViewModelInstanceBooleanBase::typeKey);
            }
            case (int)LuaAtoms::getColor:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name, ViewModelInstanceColorBase::typeKey);
            }
            case (int)LuaAtoms::getList:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name, ViewModelInstanceListBase::typeKey);
            }
            case (int)LuaAtoms::getViewModel:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name,
                                     ViewModelInstanceViewModelBase::typeKey);
            }
            case (int)LuaAtoms::getEnum:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name, ViewModelInstanceEnumBase::typeKey);
            }
            case (int)LuaAtoms::getIndex:
            {
                assert(vm->state() == L);
                return vm->pushIndex();
            }
            case (int)LuaAtoms::getImage:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name,
                                     ViewModelInstanceAssetImageBase::typeKey);
            }
            case (int)LuaAtoms::getFont:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name,
                                     ViewModelInstanceAssetFontBase::typeKey);
            }
            case (int)LuaAtoms::getBlob:
            {
                size_t namelen = 0;
                const char* name = luaL_checklstring(L, 2, &namelen);
                assert(vm->state() == L);
                return vm->pushValue(name,
                                     ViewModelInstanceAssetBlobBase::typeKey);
            }
            case (int)LuaAtoms::instance:
            case (int)LuaAtoms::newAtom:
            {
                assert(vm->state() == L);
                return vm->instance(L);
            }
            default:
                break;
        }
    }

    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               ScriptedPropertyViewModel::luaName);
    return 0;
}

static int property_vm_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        auto vm = lua_torive<ScriptedPropertyViewModel>(L, 1);

        bool error = false;
        int stackChange = property_namecall_atom(L, vm, atom, error);
        if (!error)
        {
            return stackChange;
        }
    }

    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               ScriptedPropertyViewModel::luaName);
    return 0;
}

static int property_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    const char* name = "Property";
    if (str != nullptr)
    {
        auto tag = lua_userdatatag(L, 1);
        switch (tag)
        {
            case ScriptedPropertyNumber::luaTag:
                name = ScriptedPropertyNumber::luaName;
                break;
            case ScriptedPropertyTrigger::luaTag:
                name = ScriptedPropertyTrigger::luaName;
                break;
            case ScriptedPropertyColor::luaTag:
                name = ScriptedPropertyColor::luaName;
                break;
            case ScriptedPropertyString::luaTag:
                name = ScriptedPropertyString::luaName;
                break;
            case ScriptedPropertyBoolean::luaTag:
                name = ScriptedPropertyBoolean::luaName;
                break;
            case ScriptedPropertyEnum::luaTag:
                name = ScriptedPropertyEnum::luaName;
                break;
            case ScriptedPropertyList::luaTag:
                name = ScriptedPropertyList::luaName;
                break;
            case ScriptedPropertyImage::luaTag:
                name = ScriptedPropertyImage::luaName;
                break;
            case ScriptedPropertyFont::luaTag:
                name = ScriptedPropertyFont::luaName;
                break;
            case ScriptedPropertyBlob::luaTag:
                name = ScriptedPropertyBlob::luaName;
                break;
            default:
                luaL_typeerror(L, 1, name);
                break;
        }
        auto vm = (ScriptedProperty*)lua_touserdata(L, 1);
        bool error = false;
        int stackChange = property_namecall_atom(L, vm, atom, error);
        if (!error)
        {
            return stackChange;
        }
    }
    luaL_error(L, "%s is not a valid method of %s", str, name);
    return 0;
}

ScriptedPropertyNumber::ScriptedPropertyNumber(
    lua_State* L,
    rcp<ViewModelInstanceNumber> value) :
    ScriptedProperty(L, std::move(value))
{}

ScriptedPropertyTrigger::ScriptedPropertyTrigger(
    lua_State* L,
    rcp<ViewModelInstanceTrigger> value) :
    ScriptedProperty(L, std::move(value))
{}

void ScriptedPropertyNumber::setValue(float value)
{
    if (m_instanceValue)
    {
        m_instanceValue->as<ViewModelInstanceNumber>()->propertyValue(value);
    }
}

int ScriptedPropertyNumber::pushValue()
{
    if (m_instanceValue)
    {
        lua_pushnumber(
            m_state,
            m_instanceValue->as<ViewModelInstanceNumber>()->propertyValue());
    }
    else
    {
        lua_pushnumber(m_state, 0);
    }
    return 1;
}

ScriptedPropertyColor::ScriptedPropertyColor(
    lua_State* L,
    rcp<ViewModelInstanceColor> value) :
    ScriptedProperty(L, std::move(value))
{}

void ScriptedPropertyColor::setValue(unsigned value)
{
    if (m_instanceValue)
    {
        m_instanceValue->as<ViewModelInstanceColor>()->propertyValue(
            (int)value);
    }
}

int ScriptedPropertyColor::pushValue()
{
    if (m_instanceValue)
    {
        lua_pushunsigned(m_state,
                         (unsigned)m_instanceValue->as<ViewModelInstanceColor>()
                             ->propertyValue());
    }
    else
    {
        lua_pushunsigned(m_state, 0);
    }
    return 1;
}

ScriptedPropertyString::ScriptedPropertyString(
    lua_State* L,
    rcp<ViewModelInstanceString> value) :
    ScriptedProperty(L, std::move(value))
{}

void ScriptedPropertyString::setValue(const std::string& value)
{
    if (m_instanceValue)
    {
        m_instanceValue->as<ViewModelInstanceString>()->propertyValue(value);
    }
}

int ScriptedPropertyString::pushValue()
{
    if (m_instanceValue)
    {
        lua_pushstring(m_state,
                       m_instanceValue->as<ViewModelInstanceString>()
                           ->propertyValue()
                           .c_str());
    }
    else
    {
        lua_pushstring(m_state, "");
    }
    return 1;
}

ScriptedPropertyBoolean::ScriptedPropertyBoolean(
    lua_State* L,
    rcp<ViewModelInstanceBoolean> value) :
    ScriptedProperty(L, std::move(value))
{}

void ScriptedPropertyBoolean::setValue(bool value)
{
    if (m_instanceValue)
    {
        m_instanceValue->as<ViewModelInstanceBoolean>()->propertyValue(value);
    }
}

int ScriptedPropertyBoolean::pushValue()
{
    if (m_instanceValue)
    {
        lua_pushboolean(
            m_state,
            m_instanceValue->as<ViewModelInstanceBoolean>()->propertyValue());
    }
    else
    {
        lua_pushboolean(m_state, 0);
    }
    return 1;
}

ScriptedPropertyEnum::ScriptedPropertyEnum(lua_State* L,
                                           rcp<ViewModelInstanceEnum> value) :
    ScriptedProperty(L, std::move(value))
{}

void ScriptedPropertyEnum::setValue(const std::string& value)
{
    if (m_instanceValue)
    {
        m_instanceValue->as<ViewModelInstanceEnum>()->value(value);
    }
}

int ScriptedPropertyEnum::pushValue()
{
    if (m_instanceValue)
    {
        auto vmi = m_instanceValue->as<ViewModelInstanceEnum>();
        auto vmProp = vmi->viewModelProperty()->as<ViewModelPropertyEnum>();
        if (vmProp != nullptr && vmProp->dataEnum() != nullptr)
        {
            auto values = vmProp->dataEnum()->values();
            uint32_t index = vmi->propertyValue();
            if (index < values.size())
            {
                lua_pushstring(m_state, values[index]->key().c_str());
                return 1;
            }
        }
    }
    lua_pushstring(m_state, "");
    return 1;
}

ScriptedPropertyList::ScriptedPropertyList(lua_State* L,
                                           rcp<ViewModelInstanceList> value) :
    ScriptedProperty(L, std::move(value))
{}

ScriptedPropertyList::~ScriptedPropertyList()
{
    for (const auto& pair : m_propertyRefs)
    {
        lua_unref(m_state, pair.second);
    }
}

void ScriptedPropertyList::valueChanged()
{
    m_changed = true;
    ScriptedProperty::valueChanged();
}

int ScriptedPropertyList::pushLength()
{
    if (m_instanceValue)
    {
        lua_pushinteger(m_state,
                        (int)m_instanceValue->as<ViewModelInstanceList>()
                            ->listItems()
                            .size());
    }
    else
    {
        lua_pushinteger(m_state, 0);
    }
    return 1;
}

int ScriptedPropertyList::pushValue(int index)
{
    if (m_instanceValue)
    {
        auto items = m_instanceValue->as<ViewModelInstanceList>()->listItems();

        if (m_changed)
        {
            std::unordered_map<ViewModelInstance*, int> refs;

            // re-validate references.
            for (auto& item : items)
            {
                auto vmi = item->viewModelInstance().get();
                auto itr = m_propertyRefs.find(vmi);
                if (itr != m_propertyRefs.end())
                {
                    refs[vmi] = itr->second;
                    m_propertyRefs.erase(itr);
                }
            }

            for (const auto& pair : m_propertyRefs)
            {
                lua_unref(m_state, pair.second);
            }
            m_propertyRefs = refs;

            m_changed = false;
        }

        if (index >= items.size())
        {
            lua_pushnil(m_state);
        }
        else
        {

            auto listItem = items[index];
            auto vmi = listItem->viewModelInstance();
            auto itr = m_propertyRefs.find(vmi.get());
            if (itr != m_propertyRefs.end())
            {
                lua_rawgeti(m_state, LUA_REGISTRYINDEX, itr->second);
            }
            else
            {
                lua_newrive<ScriptedViewModel>(m_state,
                                               m_state,
                                               ref_rcp(vmi->viewModel()),
                                               vmi);
                m_propertyRefs[vmi.get()] = lua_ref(m_state, -1);
            }
        }
    }
    else
    {
        lua_pushnil(m_state);
    }
    return 1;
}

ScriptedPropertyImage::ScriptedPropertyImage(
    lua_State* L,
    rcp<ViewModelInstanceAssetImage> value) :
    ScriptedProperty(L, std::move(value))
{}

void ScriptedPropertyImage::setValue(ScriptedImage* scriptedImage)
{
    if (!m_instanceValue)
    {
        return;
    }
    m_instanceValue->as<ViewModelInstanceAssetImage>()->value(
        scriptedImage != nullptr ? scriptedImage->image.get() : nullptr);
}

int ScriptedPropertyImage::pushValue()
{
    if (m_cachedValueRef != 0)
    {
        lua_rawgeti(m_state, LUA_REGISTRYINDEX, m_cachedValueRef);
        return 1;
    }
    if (m_instanceValue)
    {
        auto vmi = m_instanceValue->as<ViewModelInstanceAssetImage>();
        RenderImage* renderImage = nullptr;
        if (auto asset = vmi->asset())
        {
            renderImage = asset->renderImage();
        }
        // Fall back to the file's asset registry when no image is embedded
        // on the instance — mirrors DataBindContextValueAssetImage.
        if (renderImage == nullptr && owner() != nullptr)
        {
            if (auto scriptAsset = owner()->scriptAsset())
            {
                if (auto file = scriptAsset->file())
                {
                    auto fileAsset = file->asset(vmi->propertyValue());
                    if (fileAsset != nullptr && fileAsset->is<ImageAsset>())
                    {
                        renderImage =
                            fileAsset->as<ImageAsset>()->renderImage();
                    }
                }
            }
        }
#ifdef WITH_RIVE_TOOLS
        // Editor/Dart path: when the property is constructed without a
        // ScriptedObject owner (owner() is null), reach the File through
        // the ViewModel instead.
        if (renderImage == nullptr && owner() == nullptr)
        {
            if (auto vmInstance = vmi->viewModelInstance())
            {
                if (auto viewModel = vmInstance->viewModel())
                {
                    if (auto file = viewModel->file())
                    {
                        auto fileAsset = file->asset(vmi->propertyValue());
                        if (fileAsset != nullptr && fileAsset->is<ImageAsset>())
                        {
                            renderImage =
                                fileAsset->as<ImageAsset>()->renderImage();
                        }
                    }
                }
            }
        }
#endif
        if (renderImage != nullptr)
        {
            // Use the out-of-line `ScriptedImage::luaNew` factory rather
            // than `lua_newrive<ScriptedImage>` directly: when ore is
            // enabled, ScriptedImage holds an `rcp<ore::TextureView>` and
            // its destructor needs the full TextureView definition (this
            // TU only sees the forward decl in `rive_lua_libs.hpp`). The
            // factory lives in `lua_gpu.cpp` / `lua_image.cpp` where the
            // ore headers are visible.
            auto scriptedImage = ScriptedImage::luaNew(m_state);
            scriptedImage->image = ref_rcp(renderImage);
            m_cachedValueRef = lua_ref(m_state, -1);
            return 1;
        }
    }
    lua_pushnil(m_state);
    return 1;
}

ScriptedPropertyFont::ScriptedPropertyFont(
    lua_State* L,
    rcp<ViewModelInstanceAssetFont> value) :
    ScriptedProperty(L, std::move(value))
{}

void ScriptedPropertyFont::setValue(ScriptedFont* scriptedFont)
{
    if (!m_instanceValue)
    {
        return;
    }
    m_instanceValue->as<ViewModelInstanceAssetFont>()->value(
        scriptedFont != nullptr ? scriptedFont->font.get() : nullptr);
}

int ScriptedPropertyFont::pushValue()
{
    if (m_cachedValueRef != 0)
    {
        lua_rawgeti(m_state, LUA_REGISTRYINDEX, m_cachedValueRef);
        return 1;
    }
    if (m_instanceValue)
    {
        auto vmi = m_instanceValue->as<ViewModelInstanceAssetFont>();
        Font* font = nullptr;
        if (auto asset = vmi->asset())
        {
            font = asset->font().get();
        }
        // Fall back to the file's asset registry when no font is embedded
        // on the instance — mirrors the image property.
        if (font == nullptr && owner() != nullptr)
        {
            if (auto scriptAsset = owner()->scriptAsset())
            {
                if (auto file = scriptAsset->file())
                {
                    auto fileAsset = file->asset(vmi->propertyValue());
                    if (fileAsset != nullptr && fileAsset->is<FontAsset>())
                    {
                        font = fileAsset->as<FontAsset>()->font().get();
                    }
                }
            }
        }
#ifdef WITH_RIVE_TOOLS
        // Editor/Dart path: when the property is constructed without a
        // ScriptedObject owner, reach the File through the ViewModel.
        if (font == nullptr && owner() == nullptr)
        {
            if (auto vmInstance = vmi->viewModelInstance())
            {
                if (auto viewModel = vmInstance->viewModel())
                {
                    if (auto file = viewModel->file())
                    {
                        auto fileAsset = file->asset(vmi->propertyValue());
                        if (fileAsset != nullptr && fileAsset->is<FontAsset>())
                        {
                            font = fileAsset->as<FontAsset>()->font().get();
                        }
                    }
                }
            }
        }
#endif
        if (font != nullptr)
        {
            auto scriptedFont = lua_newrive<ScriptedFont>(m_state);
            scriptedFont->font = ref_rcp(font);
            m_cachedValueRef = lua_ref(m_state, -1);
            return 1;
        }
    }
    lua_pushnil(m_state);
    return 1;
}

ScriptedPropertyBlob::ScriptedPropertyBlob(
    lua_State* L,
    rcp<ViewModelInstanceAssetBlob> value) :
    ScriptedProperty(L, std::move(value))
{}

void ScriptedPropertyBlob::setValue(BlobAsset* blob)
{
    if (!m_instanceValue)
    {
        return;
    }
    m_instanceValue->as<ViewModelInstanceAssetBlob>()->value(blob);
}

int ScriptedPropertyBlob::pushValue()
{
    if (m_cachedValueRef != 0)
    {
        lua_rawgeti(m_state, LUA_REGISTRYINDEX, m_cachedValueRef);
        return 1;
    }
    if (m_instanceValue)
    {
        auto vmi = m_instanceValue->as<ViewModelInstanceAssetBlob>();
        rcp<FileAsset> fileAsset = nullptr;
        // A non-null asset means the blob was set directly on the instance
        // (e.g. `prop.value = ...` from a script), including a legitimately
        // empty blob. A null asset means the value is id-bound (or unset) —
        // resolve it through the file registry.
        if (auto asset = vmi->asset())
        {
            fileAsset = asset;
        }
        if (fileAsset == nullptr && owner() != nullptr)
        {
            if (auto scriptAsset = owner()->scriptAsset())
            {
                if (auto file = scriptAsset->file())
                {
                    auto candidate = file->asset(vmi->propertyValue());
                    if (candidate != nullptr && candidate->is<BlobAsset>())
                    {
                        fileAsset = candidate;
                    }
                }
            }
        }
#ifdef WITH_RIVE_TOOLS
        // Editor/Dart path: when the property is constructed without a
        // ScriptedObject owner, reach the File through the ViewModel.
        if (fileAsset == nullptr && owner() == nullptr)
        {
            if (auto vmInstance = vmi->viewModelInstance())
            {
                if (auto viewModel = vmInstance->viewModel())
                {
                    if (auto file = viewModel->file())
                    {
                        auto candidate = file->asset(vmi->propertyValue());
                        if (candidate != nullptr && candidate->is<BlobAsset>())
                        {
                            fileAsset = candidate;
                        }
                    }
                }
            }
        }
#endif
        if (fileAsset != nullptr)
        {
            auto scriptedBlob = lua_newrive<ScriptedBlob>(m_state);
            scriptedBlob->asset = fileAsset;
            m_cachedValueRef = lua_ref(m_state, -1);
            return 1;
        }
    }
    lua_pushnil(m_state);
    return 1;
}

int ScriptedEnumValues::pushValue(int index)
{
    if (m_dataEnum && m_state)
    {
        auto values = m_dataEnum->values();
        if (index >= 0 && index < values.size())
        {
            auto value = values[index];
            lua_pushstring(m_state, value->key().c_str());
            return 1;
        }
    }
    lua_pushnil(m_state);
    return 1;
}

int ScriptedEnumValues::pushLength()
{

    if (m_dataEnum)
    {
        lua_pushinteger(m_state, (int)m_dataEnum->values().size());
    }
    else
    {
        lua_pushinteger(m_state, 0);
    }
    return 1;
}

// Direct field getters: dispatched by LOP_GETTABLEKS on `prop.value` /
// `list.length`. Slow paths (property_*_index) remain reachable for
// computed-key access and lua_getfield from C.

static void property_number_direct_value(void* udata, void* result)
{
    auto* p = (ScriptedPropertyNumber*)udata;
    auto* iv = p->instanceValue();
    lua_userdatadirectfield_setnumber(
        result,
        iv ? iv->as<ViewModelInstanceNumber>()->propertyValue() : 0);
}

static void property_color_direct_value(void* udata, void* result)
{
    auto* p = (ScriptedPropertyColor*)udata;
    auto* iv = p->instanceValue();
    lua_userdatadirectfield_setnumber(
        result,
        iv ? (unsigned)iv->as<ViewModelInstanceColor>()->propertyValue() : 0);
}

static void property_boolean_direct_value(void* udata, void* result)
{
    auto* p = (ScriptedPropertyBoolean*)udata;
    auto* iv = p->instanceValue();
    lua_userdatadirectfield_setboolean(
        result,
        iv ? (iv->as<ViewModelInstanceBoolean>()->propertyValue() ? 1 : 0) : 0);
}

static void property_list_direct_length(void* udata, void* result)
{
    auto* p = (ScriptedPropertyList*)udata;
    auto* iv = p->instanceValue();
    lua_userdatadirectfield_setnumber(
        result,
        iv ? (double)iv->as<ViewModelInstanceList>()->listItems().size() : 0);
}

static int property_list_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    auto propertyList = lua_torive<ScriptedPropertyList>(L, 1);
    // if it's not an atom it should be an index into the array
    if (!key)
    {
        int index = luaL_checkinteger(L, 2);
        return propertyList->pushValue(index - 1);
    }

    switch (atom)
    {
        case (int)LuaAtoms::length:
            assert(propertyList->state() == L);
            return propertyList->pushLength();
        default:
            return 0;
    }
}

static int enum_value_length(lua_State* L)
{
    auto enumValues = lua_torive<ScriptedEnumValues>(L, 1);
    assert(enumValues->state() == L);
    return enumValues->pushLength();
}

static int enum_value_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    auto enumValues = lua_torive<ScriptedEnumValues>(L, 1);
    // if it's not an atom it should be an index into the array
    if (!key)
    {
        int index = luaL_checkinteger(L, 2);
        return enumValues->pushValue(index - 1);
    }
    return 0;
}

static int property_number_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyNumber = lua_torive<ScriptedPropertyNumber>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            assert(propertyNumber->state() == L);
            return propertyNumber->pushValue();
        default:
            return 0;
    }
}

static int property_color_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyColor = lua_torive<ScriptedPropertyColor>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            assert(propertyColor->state() == L);
            return propertyColor->pushValue();
        default:
            return 0;
    }
}

static int property_number_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyNumber = lua_torive<ScriptedPropertyNumber>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            propertyNumber->setValue(float(luaL_checknumber(L, 3)));
        default:
            return 0;
    }

    return 0;
}

static int property_color_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyColor = lua_torive<ScriptedPropertyColor>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            propertyColor->setValue(luaL_checkunsigned(L, 3));
        default:
            return 0;
    }

    return 0;
}

static int property_string_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyString = lua_torive<ScriptedPropertyString>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            assert(propertyString->state() == L);
            return propertyString->pushValue();
        default:
            return 0;
    }
}

static int property_string_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyString = lua_torive<ScriptedPropertyString>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            propertyString->setValue(luaL_checkstring(L, 3));
        default:
            return 0;
    }

    return 0;
}

static int property_boolean_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyBoolean = lua_torive<ScriptedPropertyBoolean>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            assert(propertyBoolean->state() == L);
            return propertyBoolean->pushValue();
        default:
            return 0;
    }
}

static int property_boolean_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyBoolean = lua_torive<ScriptedPropertyBoolean>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            propertyBoolean->setValue(luaL_checkboolean(L, 3));
        default:
            return 0;
    }

    return 0;
}

static int property_enum_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyEnum = lua_torive<ScriptedPropertyEnum>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            assert(propertyEnum->state() == L);
            return propertyEnum->pushValue();
        default:
            return 0;
    }
}

static int property_enum_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyEnum = lua_torive<ScriptedPropertyEnum>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
        {
            propertyEnum->setValue(luaL_checkstring(L, 3));
        }
        default:
            return 0;
    }

    return 0;
}

static int property_image_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyImage = lua_torive<ScriptedPropertyImage>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            assert(propertyImage->state() == L);
            return propertyImage->pushValue();
        default:
            return 0;
    }
}

static int property_image_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyImage = lua_torive<ScriptedPropertyImage>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
        {
            auto image = lua_torive<ScriptedImage>(L, 3);
            propertyImage->setValue(image);
            break;
        }
        default:
            return 0;
    }

    return 0;
}

static int property_font_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyFont = lua_torive<ScriptedPropertyFont>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            assert(propertyFont->state() == L);
            return propertyFont->pushValue();
        default:
            return 0;
    }
}

static int property_font_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyFont = lua_torive<ScriptedPropertyFont>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
        {
            auto font = lua_torive<ScriptedFont>(L, 3);
            propertyFont->setValue(font);
            break;
        }
        default:
            return 0;
    }

    return 0;
}

static int property_blob_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyBlob = lua_torive<ScriptedPropertyBlob>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
            assert(propertyBlob->state() == L);
            return propertyBlob->pushValue();
        default:
            return 0;
    }
}

static int property_blob_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto propertyBlob = lua_torive<ScriptedPropertyBlob>(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
        {
            if (lua_isnil(L, 3))
            {
                propertyBlob->setValue(nullptr);
                break;
            }
            // Accept raw bytes (a Luau buffer or a string) and build a blob, or
            // an existing Blob userdata.
            if (lua_isbuffer(L, 3))
            {
                size_t len = 0;
                void* data = lua_tobuffer(L, 3, &len);
                auto blobAsset = make_rcp<BlobAsset>();
                SimpleArray<uint8_t> bytes((const uint8_t*)data, len);
                blobAsset->decode(bytes, nullptr);
                propertyBlob->setValue(blobAsset.get());
                break;
            }
            if (lua_type(L, 3) == LUA_TSTRING)
            {
                size_t len = 0;
                const char* data = lua_tolstring(L, 3, &len);
                auto blobAsset = make_rcp<BlobAsset>();
                SimpleArray<uint8_t> bytes((const uint8_t*)data, len);
                blobAsset->decode(bytes, nullptr);
                propertyBlob->setValue(blobAsset.get());
                break;
            }
            auto blob = lua_torive<ScriptedBlob>(L, 3);
            propertyBlob->setValue(blob->asset ? blob->asset->as<BlobAsset>()
                                               : nullptr);
            break;
        }
        default:
            return 0;
    }

    return 0;
}

static int vm_eq(lua_State* L)
{
    auto lhs = lua_torive<ScriptedViewModel>(L, 1);
    auto rhs = lua_torive<ScriptedViewModel>(L, 2);
    lua_pushboolean(L, lhs->viewModelInstance() == rhs->viewModelInstance());
    return 1;
}

int luaopen_rive_properties(lua_State* L)
{
    {
        lua_register_rive<ScriptedViewModel>(L);

        lua_pushcfunction(L, vm_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, vm_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_pushcfunction(L, vm_eq, nullptr);
        lua_setfield(L, -2, "__eq");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }

    {
        lua_register_rive<ScriptedPropertyViewModel>(L);

        lua_pushcfunction(L, property_vm_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, property_vm_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, property_vm_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }

    {
        lua_register_rive<ScriptedPropertyNumber>(L);

        lua_pushcfunction(L, property_number_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, property_number_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedPropertyNumber::luaTag,
                                           "value",
                                           property_number_direct_value);
    }

    {
        lua_register_rive<ScriptedPropertyColor>(L);

        lua_pushcfunction(L, property_color_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, property_color_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedPropertyColor::luaTag,
                                           "value",
                                           property_color_direct_value);
    }

    {
        lua_register_rive<ScriptedPropertyString>(L);

        lua_pushcfunction(L, property_string_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, property_string_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }

    {
        lua_register_rive<ScriptedPropertyBoolean>(L);

        lua_pushcfunction(L, property_boolean_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, property_boolean_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedPropertyBoolean::luaTag,
                                           "value",
                                           property_boolean_direct_value);
    }

    {
        lua_register_rive<ScriptedPropertyEnum>(L);

        lua_pushcfunction(L, property_enum_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, property_enum_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }

    {
        lua_register_rive<ScriptedPropertyTrigger>(L);

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }

    {
        lua_register_rive<ScriptedPropertyList>(L);

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_pushcfunction(L, property_list_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedPropertyList::luaTag,
                                           "length",
                                           property_list_direct_length);
    }

    {
        lua_register_rive<ScriptedPropertyImage>(L);

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_pushcfunction(L, property_image_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, property_image_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }

    {
        // No metatable, but the rcp<Font> member needs its destructor run
        // when the userdata is collected.
        lua_register_rive<ScriptedFont>(L);
    }

    {
        lua_register_rive<ScriptedPropertyFont>(L);

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_pushcfunction(L, property_font_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, property_font_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }

    {
        lua_register_rive<ScriptedPropertyBlob>(L);

        lua_pushcfunction(L, property_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_pushcfunction(L, property_blob_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, property_blob_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }

    {
        lua_register_rive<ScriptedEnumValues>(L);

        lua_pushcfunction(L, enum_value_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, enum_value_length, nullptr);
        lua_setfield(L, -2, "__len");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }

    return 0;
}
#endif
