#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#include "libhydrogen.h"
#include "rive/importers/script_asset_importer.hpp"
#endif
#include "rive/assets/script_asset.hpp"
#include "rive/bytecode_header.hpp"
#include "rive/file.hpp"
#include "rive/script_input_artboard.hpp"
#include "rive/script_input_boolean.hpp"
#include "rive/script_input_color.hpp"
#include "rive/script_input_number.hpp"
#include "rive/script_input_string.hpp"
#include "rive/script_input_trigger.hpp"
#include "rive/script_input_viewmodel_property.hpp"
#include "rive/scripted/scripted_drawable.hpp"
#include "rive/scripted/scripted_layout.hpp"
#include "rive/scripted/scripted_object.hpp"

using namespace rive;

ScriptInput* ScriptInput::from(Core* component)
{
    switch (component->coreType())
    {
        case ScriptInputArtboard::typeKey:
            return component->as<ScriptInputArtboard>();
        case ScriptInputBoolean::typeKey:
            return component->as<ScriptInputBoolean>();
        case ScriptInputColor::typeKey:
            return component->as<ScriptInputColor>();
        case ScriptInputNumber::typeKey:
            return component->as<ScriptInputNumber>();
        case ScriptInputString::typeKey:
            return component->as<ScriptInputString>();
        case ScriptInputTrigger::typeKey:
            return component->as<ScriptInputTrigger>();
        case ScriptInputViewModelProperty::typeKey:
            return component->as<ScriptInputViewModelProperty>();
    }
    return nullptr;
}

void ScriptInput::initScriptedValue() {}

bool OptionalScriptedMethods::verifyImplementation(ScriptedObject* object,
                                                   LuaState* luaState)
{
#ifdef WITH_RIVE_SCRIPTING
    auto state = luaState->state;
    lua_pushvalue(state, -1);
    if (static_cast<lua_Status>(rive_lua_pcall(state, 0, 1)) != LUA_OK)
    {
        fprintf(stderr, "Verifying implementation pcall failed\n");
        rive_lua_pop(state, 1);
        return false;
    }
    if (static_cast<lua_Type>(lua_type(state, -1)) != LUA_TTABLE)
    {
        fprintf(stderr, "Verifying implementation not a table?\n");
        rive_lua_pop(state, 1);
        return false;
    }
    m_implementedMethods = 0;

    auto scriptProtocol = object->scriptProtocol();
    if (scriptProtocol == ScriptProtocol::node ||
        scriptProtocol == ScriptProtocol::layout ||
        scriptProtocol == ScriptProtocol::converter ||
        scriptProtocol == ScriptProtocol::pathEffect)
    {
        if (static_cast<lua_Type>(lua_getfield(state, -1, "update")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_updatesBit;
        }
        rive_lua_pop(state, 1);
        if (static_cast<lua_Type>(lua_getfield(state, -1, "advance")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_advancesBit;
        }
        rive_lua_pop(state, 1);
        if (static_cast<lua_Type>(lua_getfield(state, -1, "pointerDown")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_wantsPointerDownBit;
        }
        rive_lua_pop(state, 1);
        if (static_cast<lua_Type>(lua_getfield(state, -1, "pointerUp")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_wantsPointerUpBit;
        }
        rive_lua_pop(state, 1);
        if (static_cast<lua_Type>(lua_getfield(state, -1, "pointerMove")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_wantsPointerMoveBit;
        }
        rive_lua_pop(state, 1);
        if (static_cast<lua_Type>(lua_getfield(state, -1, "pointerCanceled")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_wantsPointerCancelBit;
        }
        rive_lua_pop(state, 1);
        if (static_cast<lua_Type>(lua_getfield(state, -1, "pointerExit")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_wantsPointerExitBit;
        }
        rive_lua_pop(state, 1);
        if (static_cast<lua_Type>(lua_getfield(state, -1, "init")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_initsBit;
        }
        rive_lua_pop(state, 1);
    }
    if (scriptProtocol == ScriptProtocol::layout)
    {
        if (static_cast<lua_Type>(lua_getfield(state, -1, "measure")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_measuresBit;
        }
        rive_lua_pop(state, 1);
        if (static_cast<lua_Type>(lua_getfield(state, -1, "draw")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_drawsBit;
        }
        rive_lua_pop(state, 1);
    }
    else if (scriptProtocol == ScriptProtocol::node)
    {
        if (static_cast<lua_Type>(lua_getfield(state, -1, "draw")) ==
            LUA_TFUNCTION)
        {
            m_implementedMethods |= m_drawsBit;
        }
        rive_lua_pop(state, 1);
    }
    rive_lua_pop(state, 1);
    return true;
#else
    return false;
#endif
}

#ifdef WITH_RIVE_SCRIPTING
LuaState* ScriptAsset::vm()
{
    if (m_file == nullptr)
    {
        return nullptr;
    }
    // We get the scripting VM from File for now, however,
    // this will need to change if/when we support multiple VMs
    return m_file->scriptingVM();
}
#endif

bool ScriptAsset::initScriptedObject(ScriptedObject* object)
{
#ifdef WITH_RIVE_SCRIPTING
    if (vm() == nullptr)
    {
        return false;
    }
    return initScriptedObjectWith(object);
#else
    return false;
#endif
}

#if defined(WITH_RIVE_SCRIPTING)
void ScriptAsset::registrationComplete(int ref)
{
    if (isModule())
    {
        m_scriptRegistered = true;
    }
    else
    {
        generatorFunctionRef(ref);
    }
}
#endif

bool ScriptAsset::initScriptedObjectWith(ScriptedObject* object)
{
#if defined(WITH_RIVE_SCRIPTING)
    if (vm() == nullptr)
    {
        return false;
    }
    if (generatorFunctionRef() == 0)
    {
        fprintf(stderr,
                "ScriptAsset doesn't have a generator function %s\n",
                name().c_str());
        return false;
    }
    auto vmState = vm()->state;
    rive_lua_pushRef(vmState, generatorFunctionRef());

    if (!m_initted)
    {
        if (!verifyImplementation(object, vm()))
        {
            fprintf(stderr,
                    "ScriptAsset failed to verify method implementation %s\n",
                    name().c_str());
            rive_lua_pop(vmState, 1);
            return false;
        }
        m_initted = true;
    }
    object->implementedMethods(implementedMethods());
    return object->scriptInit(vm());
#else
    return false;
#endif
}

bool ScriptAsset::decode(SimpleArray<uint8_t>& data, Factory* factory)
{
#ifdef WITH_RIVE_SCRIPTING
    m_verified = false;

    // For in-band bytecode, isSigned should always be false (signature is
    // stored separately for aggregate verification).
    BytecodeHeader header(Span<const uint8_t>(data.data(), data.size()));
    if (!header.isValid())
    {
        return false;
    }

    // Store just the bytecode (without header) for later verification and use.
    auto bytecode = header.bytecode();
    m_bytecode = SimpleArray<uint8_t>(bytecode.data(), bytecode.size());
#endif
    return true;
}

bool ScriptAsset::bytecode(Span<uint8_t> data)
{
#ifdef WITH_RIVE_SCRIPTING
    BytecodeHeader header(Span<const uint8_t>(data.data(), data.size()));
    if (!header.isValid())
    {
        m_verified = false;
        return false;
    }

    auto bytecode = header.bytecode();

    if (!header.isSigned())
    {
        // Unsigned bytecode - mark as unverified
        m_verified = false;
        m_bytecode = SimpleArray<uint8_t>(bytecode.data(), bytecode.size());
        return true;
    }

    auto signature = header.signature();
    if (hydro_sign_verify(signature.data(),
                          bytecode.data(),
                          bytecode.size(),
                          "RiveCode",
                          g_scriptVerificationPublicKey) != 0)
    {
        // Forged.
        m_verified = false;
        return false;
    }
    m_verified = true;
    m_bytecode = SimpleArray<uint8_t>(bytecode.data(), bytecode.size());
#endif
    return true;
}