#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.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_viewmodel.hpp"
#include "rive/viewmodel/viewmodel_instance_list.hpp"
#include "rive/viewmodel/viewmodel_instance_enum.hpp"
#include "rive/viewmodel/viewmodel_instance_list_item.hpp"

#include <math.h>
#include <stdio.h>

using namespace rive;

static void pushViewModelInstanceValue(lua_State* L,
                                       rcp<ViewModel> viewModel,
                                       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:
            lua_newrive<ScriptedPropertyViewModel>(
                L,
                L,
                viewModel,
                ref_rcp(propValue->as<ViewModelInstanceViewModel>()));
            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()
{
    m_instanceValue->removeDelegate(this);
    clearListeners();
}

ScriptedPropertyViewModel::~ScriptedPropertyViewModel()
{
    lua_unref(m_state, m_valueRef);
}

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);
        }
    }
    m_listeners.clear();
}

ScriptedProperty::ScriptedProperty(lua_State* L,
                                   rcp<ViewModelInstanceValue> value) :
    m_state(L), m_instanceValue(std::move(value))
{
    m_instanceValue->addDelegate(this);
}

void ScriptedProperty::valueChanged()
{
    // 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))
    {
        int callbackRef = lua_ref(m_state, 2);
        m_listeners.push_back({callbackRef});
        return 0;
    }
    else if (lua_isfunction(m_state, 3))
    {
        int userdataRef = lua_ref(m_state, 2);
        int callbackRef = lua_ref(m_state, 3);
        m_listeners.push_back({callbackRef, userdataRef});
        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);
            }
            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->is<ViewModelInstanceViewModel>())
    {
        auto instanceValue = m_instanceValue->as<ViewModelInstanceViewModel>();
        auto parentViewModelInstance = instanceValue->parentViewModelInstance();
        auto viewModelInstance = scriptedViewModel->mutableViewModelInstance();
        parentViewModelInstance->replaceViewModelByProperty(
            instanceValue,
            rcp<ViewModelInstance>(viewModelInstance));
        // Invalidate cached Lua-side value so the next push reflects the new
        // instance.
        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)
{}

ScriptedViewModel::~ScriptedViewModel()
{
    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;
}

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);
        return 1;
    }
    // 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;
            }
        }
    }
    else
    {
        auto propValue = vmi->propertyValue(name);
        if (propValue == nullptr ||
            (coreType != 0 && propValue->coreType() != coreType))
        {
            lua_pushnil(m_state);
        }
        else
        {
            pushViewModelInstanceValue(m_state, m_viewModel, propValue);
        }
    }
    m_propertyRefs[name] = lua_ref(m_state, -1);
    return 1;
}

int ScriptedPropertyViewModel::pushValue()
{
    // N.B. we'll need to invalidate m_valueRef if the viewmodel's value on the
    // property changes.
    if (m_valueRef != 0)
    {
        lua_rawgeti(m_state, LUA_REGISTRYINDEX, m_valueRef);
        return 1;
    }
    if (m_instanceValue)
    {
        lua_newrive<ScriptedViewModel>(
            m_state,
            m_state,
            m_viewModel,
            m_instanceValue->as<ViewModelInstanceViewModel>()
                ->referenceViewModelInstance());
    }
    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;
}

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::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);
            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::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;
            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;
}

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;
}

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 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_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_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_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_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
