-- Smoke: HDG.TagData port.
-- Verbatim port of HousingDecorGuide/modules/HDG_TagData.lua with a GetLabel
-- addition. Covers:
--   - GetCategory bucket mapping (Size->Sizes, Faction->Factions, ...)
--   - "Other" fallback for unknown groupName
--   - GetLabel returns the tagName from the Blizzard struct
--   - Lazy build: first call populates the cache; subsequent calls reuse
--   - Invalidate() clears both maps
--   - nil-safety when GetAllFilterTagGroups returns nil or a missing group

dofile("wow_mock.lua")

-- Fake the Blizzard housing catalog API. Structure matches the live shape
-- documented at Reference/HOUSING_CATALOG_API.md: GetAllFilterTagGroups
-- returns { { groupName, tags = { { tagID, tagName, ... }, ... } }, ... }.
local function setCatalogGroups(groups)
    _G.C_HousingCatalog = _G.C_HousingCatalog or {}
    _G.C_HousingCatalog.GetAllFilterTagGroups = function() return groups end
end

setCatalogGroups({
    { groupName = "Size", tags = {
        { tagID = 66, tagName = "Small"  },
        { tagID = 67, tagName = "Medium" },
        { tagID = 68, tagName = "Large"  },
    } },
    { groupName = "Faction", tags = {
        { tagID = 100, tagName = "Alliance" },
        { tagID = 101, tagName = "Horde"    },
    } },
    { groupName = "Expansion", tags = {
        { tagID = 200, tagName = "Midnight"  },
        { tagID = 201, tagName = "Khaz Algar" },
    } },
    { groupName = "Style", tags = {
        { tagID = 300, tagName = "Rustic" },
        { tagID = 301, tagName = "Royal"  },
    } },
    -- Anything else buckets to "Other".
    { groupName = "Subject", tags = {
        { tagID = 400, tagName = "Chair" },
    } },
    { groupName = "Condition", tags = {
        { tagID = 500, tagName = "Pristine" },
    } },
})

dofile("../Core/HDGR_TagData.lua")

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

-- ============================================================================
-- 1. GetCategory bucket mapping
-- ============================================================================

assertEq(HDG.TagData.GetCategory(66),  "Sizes",      "Size group -> 'Sizes'")
assertEq(HDG.TagData.GetCategory(67),  "Sizes",      "Size group -> 'Sizes' (2)")
assertEq(HDG.TagData.GetCategory(100), "Factions",   "Faction group -> 'Factions'")
assertEq(HDG.TagData.GetCategory(200), "Expansions", "Expansion group -> 'Expansions'")
assertEq(HDG.TagData.GetCategory(300), "Styles",     "Style group -> 'Styles'")

-- Unknown groupName -> "Other" bucket
assertEq(HDG.TagData.GetCategory(400), "Other", "Subject groupName -> 'Other'")
assertEq(HDG.TagData.GetCategory(500), "Other", "Condition groupName -> 'Other'")

-- Unknown tagID also -> "Other" (default fallback)
assertEq(HDG.TagData.GetCategory(99999), "Other", "unknown tagID -> 'Other' fallback")

-- ============================================================================
-- 2. GetLabel returns tagName
-- ============================================================================

assertEq(HDG.TagData.GetLabel(66),  "Small",      "GetLabel(66) = 'Small'")
assertEq(HDG.TagData.GetLabel(101), "Horde",      "GetLabel(101) = 'Horde'")
assertEq(HDG.TagData.GetLabel(200), "Midnight",   "GetLabel(200) = 'Midnight'")
assertEq(HDG.TagData.GetLabel(400), "Chair",      "GetLabel(400) = 'Chair'  (Other-bucket tag still labeled)")
assertEq(HDG.TagData.GetLabel(99999), nil,        "GetLabel(unknown) = nil")

-- ============================================================================
-- 3. Invalidate() clears the cache
-- ============================================================================

-- Replace the API with a new (smaller) group set; without Invalidate the cache
-- would still hold the old data.
setCatalogGroups({
    { groupName = "Size", tags = {
        { tagID = 999, tagName = "Huge" },
    } },
})

-- Before Invalidate -- old data still cached
assertEq(HDG.TagData.GetCategory(66), "Sizes",
    "before Invalidate: old cache still serves (66 was 'Sizes')")
assertEq(HDG.TagData.GetLabel(999), nil,
    "before Invalidate: new tag not visible (cache stale)")

HDG.TagData.Invalidate()

-- After Invalidate -- fresh build picks up new data
assertEq(HDG.TagData.GetCategory(66), "Other",
    "after Invalidate: old tag 66 not in new groups -> 'Other' fallback")
assertEq(HDG.TagData.GetCategory(999), "Sizes",
    "after Invalidate: new tag 999 in 'Sizes' group")
assertEq(HDG.TagData.GetLabel(999), "Huge",
    "after Invalidate: new tag's label resolves")

-- ============================================================================
-- 4. Nil-safety: API not present yet
-- ============================================================================

_G.C_HousingCatalog = nil
HDG.TagData.Invalidate()

assertEq(HDG.TagData.GetCategory(66), "Other",
    "GetCategory with no catalog API -> 'Other' fallback (no crash)")
assertEq(HDG.TagData.GetLabel(66), nil,
    "GetLabel with no catalog API -> nil (no crash)")

-- Restore for any downstream tests in the same run.
setCatalogGroups({})
HDG.TagData.Invalidate()

io.write("test_tagdata_smoke.lua passed\n")
