// The savegame surface. The assertions live in
// savegame.lua.
//
// The fake below stands in for the save store: a normal pool of three slots
// with the first one taken, and two quick saves on disk.

#include <harness/fake_calls.h>
#include <harness/lua_surface.h>

#include <trx/game/game_flow.h>
#include <trx/game/savegame.h>

static SAVEGAME_SLOT_REF m_SavedSlot = { .index = -1 };

static int32_t m_LoadedParam = -1;

// The slot the fake ended up holding is state, not a call, so it is read here.
static int M_FakeReset(lua_State *const L)
{
    FakeCalls_Reset();
    m_LoadedParam = -1;
    m_SavedSlot = (SAVEGAME_SLOT_REF) { .index = -1 };
    return 0;
}

static int M_FakeCalls(lua_State *const L)
{
    FakeCalls_Push(L);
    lua_pushinteger(L, m_LoadedParam);
    lua_setfield(L, -2, "loaded_param");
    lua_pushinteger(L, m_SavedSlot.index);
    lua_setfield(L, -2, "saved_index");
    lua_pushinteger(L, m_SavedSlot.pool);
    lua_setfield(L, -2, "saved_pool");
    return 1;
}

int32_t SG_Manager_GetSlotCount(const SAVEGAME_SLOT_POOL pool)
{
    return pool == SAVEGAME_SLOT_POOL_QUICK ? 4 : 3;
}

int32_t SG_Manager_GetQuickVisualCount(void)
{
    return 2;
}

SAVEGAME_SLOT_REF SG_Manager_NormalSlot(const int32_t index)
{
    return (SAVEGAME_SLOT_REF) { .pool = SAVEGAME_SLOT_POOL_NORMAL,
                                 .index = index };
}

SAVEGAME_SLOT_REF SG_Manager_QuickFromVisualIndex(const int32_t visual_index)
{
    return (SAVEGAME_SLOT_REF) { .pool = SAVEGAME_SLOT_POOL_QUICK,
                                 .index = visual_index };
}

// The first normal slot holds a save; every other slot is empty.
bool SG_Manager_IsSlotFree(const SAVEGAME_SLOT_REF slot)
{
    return !(slot.pool == SAVEGAME_SLOT_POOL_NORMAL && slot.index == 0);
}

int32_t SG_Manager_SlotToParam(const SAVEGAME_SLOT_REF slot)
{
    return slot.index;
}

SAVEGAME_SLOT_REF SG_Manager_GetNextQuickSlot(void)
{
    return (SAVEGAME_SLOT_REF) { .pool = SAVEGAME_SLOT_POOL_QUICK, .index = 3 };
}

bool SG_Manager_IsValidSlotRef(const SAVEGAME_SLOT_REF slot)
{
    return slot.index >= 0;
}

bool Savegame_Save(const SAVEGAME_SLOT_REF slot)
{
    m_SavedSlot = slot;
    return true;
}

void GF_OverrideCommand(const GF_COMMAND command)
{
    m_LoadedParam = command.param;
}

int main(void)
{
    const LUA_SURFACE_TEST test = {
        .fake_reset = M_FakeReset,
        .module = "savegame",
        .tests = "api/savegame",
        .seal = true,
        .fake_calls = M_FakeCalls,
    };
    return LuaSurface_Run(&test);
}
