-- test_lumber_state.lua
-- ============================================================================
-- Phase 3 lumber state-shape smoke: verifies the lumber slots ship with the
-- correct default factory shapes AND that EnsureStateShape backfills them
-- on a SavedVariables-loaded state missing the lumber slot (migration path).

dofile("wow_mock.lua")
dofile("../Core/HDGR_SchemeConstants.lua")
dofile("../Core/HDGR_Constants.lua")
dofile("../Core/HDGR_Actions.lua")
dofile("../Core/HDGR_Resolvers.lua")
dofile("../Core/HDGR_Format.lua")
dofile("../Core/HDGR_Paths.lua")
dofile("../Core/HDGR_Log.lua")
dofile("../Core/HDGR_Memo.lua")
dofile("../Core/HDGR_TableUtils.lua")
dofile("../Core/HDGR_Modules.lua")
dofile("../Core/HDGR_StoreFurnishings.lua")
dofile("../Core/HDGR_Store.lua")

local function assertTrue(v, label) if not v then error(label, 2) end end
local function assertEq(a, b, label)
    if a ~= b then error(label .. ": expected " .. tostring(b) .. ", got " .. tostring(a), 2) end
end

-- ===== 1. Default-state factory ships the lumber slots ====================
HDG_DB = {}
HDG.Store:LoadFromSavedVariables()
local state = HDG.Store:GetState()

-- account.lumber.config
assertTrue(state.account.lumber, "account.lumber slot exists")
assertTrue(state.account.lumber.config, "account.lumber.config slot exists")
assertEq(state.account.lumber.config.windowVisible,     false, "windowVisible default")
assertEq(state.account.lumber.config.radarCollapsed,    false, "radarCollapsed default")
assertEq(state.account.lumber.config.radarScale,        1.0,   "radarScale default")
assertEq(state.account.lumber.config.autoShowOnHarvest, true,  "autoShowOnHarvest default")
assertTrue(type(state.account.lumber.config.position) == "table", "position is a table")
assertEq(state.account.lumber.config.position.x, 100,   "position.x default")
assertEq(state.account.lumber.config.position.y, -150,  "position.y default")

-- account.lumber.sessions: empty map, ready for LUMBER_SESSION_START to populate
assertTrue(type(state.account.lumber.sessions) == "table", "sessions is a table")
assertEq(next(state.account.lumber.sessions), nil, "sessions starts empty")

-- session.lumber
assertTrue(state.session.lumber, "session.lumber slot exists")
assertEq(state.session.lumber.activeFarmingID, nil, "activeFarmingID default nil")
assertEq(state.session.lumber.tick, 0, "tick starts at 0")
assertTrue(type(state.session.lumber.blips) == "table", "blips is a table")
assertEq(#state.session.lumber.blips, 0, "blips starts empty")

-- ===== 2. EnsureStateShape backfills the lumber slot on migration =========
-- Simulate a SavedVariables snapshot from before the lumber feature shipped:
-- state.account exists but state.account.lumber is nil. Reload should fill
-- the slot without touching other persistent state.
HDG_DB = {
    account = {
        schemaVersion = HDG.Constants.SCHEMA_VERSION,
        config        = { debug = true, scheme = "Mocha" },  -- pre-existing user prefs
        -- intentionally NO lumber slot
    },
}
HDG.Store:LoadFromSavedVariables()
local migrated = HDG.Store:GetState()

assertTrue(migrated.account.lumber, "account.lumber backfilled on migration")
assertTrue(migrated.account.lumber.config, "config backfilled")
assertEq(migrated.account.lumber.config.windowVisible, false, "windowVisible default after migration")
assertEq(migrated.account.lumber.config.radarScale, 1.0, "radarScale default after migration")
assertEq(migrated.account.config.scheme, "Mocha", "pre-existing config preserved through migration")
assertEq(migrated.account.config.debug, true, "pre-existing debug flag preserved")

-- session.lumber backfills too (rebuilt every session, so just verify present)
assertTrue(migrated.session.lumber, "session.lumber present after migration")
assertEq(migrated.session.lumber.activeFarmingID, nil, "fresh session activeFarmingID nil")

-- ===== 3. Partial config backfills missing keys but keeps existing =======
HDG_DB = {
    account = {
        schemaVersion = HDG.Constants.SCHEMA_VERSION,
        lumber = {
            config = {
                windowVisible = true,                    -- user had window open
                position = { x = 500, y = -300 },        -- user dragged
                -- radarCollapsed / radarScale / autoShowOnHarvest missing
            },
            sessions = {
                ["Vamoose-Frostmourne"] = {
                    [245586] = { startedAt = 12345, startCount = 5 },  -- Ironwood
                },
            },
        },
    },
}
HDG.Store:LoadFromSavedVariables()
local partial = HDG.Store:GetState()
assertEq(partial.account.lumber.config.windowVisible, true,  "user windowVisible preserved")
assertEq(partial.account.lumber.config.position.x,    500,   "user position preserved")
assertEq(partial.account.lumber.config.radarCollapsed, false, "missing field backfilled from default")
assertEq(partial.account.lumber.config.radarScale,     1.0,   "missing scale backfilled")
assertEq(partial.account.lumber.config.autoShowOnHarvest, true, "missing autoShow backfilled")
-- Sessions preserved verbatim through the ensure path
assertTrue(partial.account.lumber.sessions["Vamoose-Frostmourne"], "user session preserved")
assertEq(partial.account.lumber.sessions["Vamoose-Frostmourne"][245586].startCount, 5,
         "session detail preserved")

print("test_lumber_state.lua passed")
