#if defined(WITH_RIVE_SCRIPTING) && defined(WITH_RIVE_SCRIPTNET)

#include "rive/lua/rive_lua_libs.hpp"
#include "rive/artboard.hpp"
#include "rive/bindable_artboard.hpp"
#include "rive/file.hpp"
#include "rive/scripted/decoded_file.hpp"
#include "rive/viewmodel/viewmodel_instance.hpp"
#include "lua.h"
#include "lualib.h"

using namespace rive;

ScriptedRiveFile::ScriptedRiveFile() = default;
ScriptedRiveFile::~ScriptedRiveFile() = default;

ScriptedBindableArtboard::ScriptedBindableArtboard() = default;
ScriptedBindableArtboard::~ScriptedBindableArtboard() = default;

int ScriptedBindableArtboard::pushData(lua_State* L)
{
  if (viewModel == nullptr)
  {
    lua_pushnil(L);
    return 1;
  }
  if (m_dataCache.push(L, viewModel))
  {
    return 1;
  }
  lua_newrive<ScriptedViewModel>(
      L,
      L,
      ref_rcp(viewModel->viewModel()),
      viewModel);
  m_dataCache.store(L, viewModel);
  return 1;
}

namespace
{

// ── RiveFile ───────────────────────────────────────────────────────────────

int riveFileIndex(lua_State* L)
{
  auto* self = lua_torive<ScriptedRiveFile>(L, 1);
  int atom;
  const char* key = lua_tostringatom(L, 2, &atom);
  if (key == nullptr)
  {
    luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
    return 0;
  }
  switch (atom)
  {
    case (int)LuaAtoms::artboardNames:
    {
      size_t count = self->file->artboardCount();
      lua_createtable(L, (int)count, 0);
      for (size_t i = 0; i < count; i++)
      {
        const std::string& name = self->file->artboard(i)->name();
        lua_pushlstring(L, name.data(), name.size());
        lua_rawseti(L, -2, (int)i + 1);
      }
      return 1;
    }
    default:
      break;
  }
  luaL_error(
      L,
      "'%s' is not a valid index of %s",
      key,
      ScriptedRiveFile::luaName);
  return 0;
}

int riveFileNamecall(lua_State* L)
{
  int atom;
  const char* name = lua_namecallatom(L, &atom);
  auto* self = lua_torive<ScriptedRiveFile>(L, 1);
  if (name != nullptr && atom == (int)LuaAtoms::bindableArtboard)
  {
    const char* artboardName = lua_isnoneornil(L, 2) ? nullptr
                                                     : luaL_checkstring(L, 2);
    auto* bindable = lua_newrive<ScriptedBindableArtboard>(L);
    DecodedBindable decoded = decodedBindable(*self->file, artboardName);
    if (decoded.artboard == nullptr)
    {
      lua_pop(L, 1);
      lua_pushnil(L);
      return 1;
    }
    bindable->artboard = std::move(decoded.artboard);
    bindable->viewModel = std::move(decoded.viewModel);
    return 1;
  }
  luaL_error(
      L,
      "%s is not a valid method of %s",
      name != nullptr ? name : "?",
      ScriptedRiveFile::luaName);
  return 0;
}

// ── BindableArtboard ───────────────────────────────────────────────────────

int bindableArtboardIndex(lua_State* L)
{
  auto* self = lua_torive<ScriptedBindableArtboard>(L, 1);
  int atom;
  const char* key = lua_tostringatom(L, 2, &atom);
  if (key == nullptr)
  {
    luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
    return 0;
  }
  switch (atom)
  {
    case (int)LuaAtoms::name:
    {
      const std::string& name = self->artboard->artboard()->name();
      lua_pushlstring(L, name.data(), name.size());
      return 1;
    }
    case (int)LuaAtoms::data:
      return self->pushData(L);
    default:
      break;
  }
  luaL_error(
      L,
      "'%s' is not a valid index of %s",
      key,
      ScriptedBindableArtboard::luaName);
  return 0;
}

// Wrappers are minted per read, so equality is by the artboard they carry.
int bindableArtboardEq(lua_State* L)
{
  auto* lhs = lua_torive<ScriptedBindableArtboard>(L, 1);
  auto* rhs = lua_torive<ScriptedBindableArtboard>(L, 2);
  lua_pushboolean(L, lhs->artboard == rhs->artboard);
  return 1;
}
} // namespace

// ── context:decodeFile(data) ───────────────────────────────────────────────

// Decodes on the calling thread: import calls into the Factory and runs the
// file's module bodies, neither of which is safe on a worker. The returned
// Promise is already settled, which keeps the signature open to an
// off-thread decode later.
int context_decodeFile_impl(lua_State* L)
{
  // Luau errors longjmp past C++ destructors, so every check that can raise
  // runs before anything is decoded.
  size_t length = 0;
  const void* data = nullptr;
  if (lua_isbuffer(L, 2))
  {
    data = lua_tobuffer(L, 2, &length);
  }
  else
  {
    luaL_typeerror(L, 2, "buffer");
    return 0;
  }
  if (data == nullptr || length == 0)
  {
    luaL_error(L, "decodeFile: empty buffer");
    return 0;
  }
  ScriptingContext* context = ScriptingContext::from(L);
  Factory* factory = context != nullptr ? context->factory() : nullptr;
  if (factory == nullptr)
  {
    luaL_error(
        L,
        "decodeFile: this Lua state has no factory to decode "
        "with");
    return 0;
  }

  auto* promise = lua_newrive<ScriptedPromise>(L, lua_mainthread(L));
  int promiseIdx = lua_gettop(L);
  // Allocated before the import so no allocation can fail while the decoded
  // file is held only by a C++ local.
  auto* riveFile = lua_newrive<ScriptedRiveFile>(L);
  int fileIdx = lua_gettop(L);

  ImportResult result = ImportResult::malformed;
  riveFile->file = importDecodedFile(
      Span<const uint8_t>(static_cast<const uint8_t*>(data), length),
      factory,
      &result);
  if (riveFile->file != nullptr)
  {
    promise->resolve(L, fileIdx);
  }
  else
  {
    lua_pushstring(
        L,
        result == ImportResult::unsupportedVersion
            ? "unsupportedVersion: not a Rive file this "
              "runtime can read"
            : "malformed: not a Rive file");
    promise->reject(L, lua_gettop(L));
    lua_pop(L, 1);
  }
  lua_pushvalue(L, promiseIdx);
  return 1;
}

int luaopen_rive_file(lua_State* L)
{
  {
    lua_register_rive<ScriptedRiveFile>(L);

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

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

    lua_setreadonly(L, -1, true);
    lua_pop(L, 1); // pop the metatable
  }
  {
    lua_register_rive<ScriptedBindableArtboard>(L);

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

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

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

#endif
