-- test_module_ownership.lua
-- ============================================================================
-- Verifies invariant §13: each Blizzard C_* namespace is claimed by AT MOST
-- one observer module. Modules:Boot() runs ValidateOwnership() at boot; a
-- conflict errors loud. This test asserts:
--   - the three real observer modules claim disjoint namespaces
--   - introducing a duplicate-claim module makes Boot fail loud
--   - VDS.Modules.ValidateOwnership returns cleanly when the registry is
--     valid

---@diagnostic disable: undefined-global
dofile("wow_mock.lua")
dofile("../Core/VDS_Constants.lua")
dofile("../Core/VDS_SchemeConstants.lua")
dofile("../Core/VDS_Paths.lua")
dofile("../Core/VDS_Log.lua")
dofile("../Core/VDS_Store.lua")
dofile("../Core/VDS_ActionMeta.lua")
VDS.Store:ValidateActionMetaExhaustiveness()
VDS_DB = {}
VDS.Store:LoadFromSavedVariables()

-- Engine pieces the Module registry needs
dofile("../UI/VDS_Modules.lua")
dofile("../UI/VDS_BlizzardEvents.lua")

-- Mock C_AddOns so LiveCustomizeObserver's onEnable can run.
_G.C_AddOns = _G.C_AddOns or {}
function _G.C_AddOns.IsAddOnLoaded() return false end

-- Mock the live + ownership module dependencies' Blizzard surface enough for
-- the file-load + ValidateOwnership pass. We are NOT testing the observers'
-- runtime behavior here, just their namespace declaration.
_G.C_DyeColor = _G.C_DyeColor or {
    GetAllDyeColorCategories = function() return {} end,
    GetDyeColorsInCategory   = function() return {} end,
    GetDyeColorInfo          = function() return nil end,
}
_G.C_HousingCustomizeMode = _G.C_HousingCustomizeMode or {
    GetSelectedDecorInfo = function() return nil end,
}
_G.C_HousingCatalog = _G.C_HousingCatalog or {
    CreateCatalogSearcher          = function() return nil end,
    GetCatalogEntryInfoByRecordID  = function() return nil end,
    GetCatalogEntryInfoByItem      = function() return nil end,
}

dofile("../Modules/VDS_SessionIdentity.lua")
dofile("../Modules/VDS_StaticData.lua")
dofile("../Modules/VDS_DyeOwnershipObserver.lua")
dofile("../Modules/VDS_LiveCustomizeObserver.lua")
dofile("../Modules/VDS_DecorInfoResolver.lua")

local function assert_(v, label) if not v then error(label, 2) end end

print("Module ownership:")

-- ============================================================================
-- 1. Each known observer declares its namespace
-- ============================================================================

local function moduleOwns(name, ns)
    local m = VDS.Modules._registry[name]
    if not m then return false end
    for _, claimed in ipairs(m.ownsBlizzardNamespaces or {}) do
        if claimed == ns then return true end
    end
    return false
end

assert_(moduleOwns("DyeOwnershipObserver", "C_DyeColor"),
    "DyeOwnershipObserver does not declare ownership of C_DyeColor")
assert_(moduleOwns("LiveCustomizeObserver", "C_HousingCustomizeMode"),
    "LiveCustomizeObserver does not declare ownership of C_HousingCustomizeMode")
assert_(moduleOwns("DecorInfoResolver", "C_HousingCatalog"),
    "DecorInfoResolver does not declare ownership of C_HousingCatalog (ADR-001)")
print("  [OK] every observer module declares its namespace")

-- ============================================================================
-- 2. Disjoint check passes for the real registry
-- ============================================================================

local ok, err = pcall(function() VDS.Modules:ValidateOwnership() end)
assert_(ok, "ValidateOwnership failed on a valid registry: " .. tostring(err))
print("  [OK] ValidateOwnership returns cleanly on the real (disjoint) registry")

-- ============================================================================
-- 3. Adding a duplicate-claim module makes the check fail
-- ============================================================================

VDS.Modules:Declare({
    name = "RogueObserver",
    ownsBlizzardNamespaces = { "C_DyeColor" },  -- conflicts with DyeOwnershipObserver
})

local conflictOk, conflictErr = pcall(function() VDS.Modules:ValidateOwnership() end)
assert_(not conflictOk, "ValidateOwnership did not detect duplicate claim on C_DyeColor")
assert_(tostring(conflictErr):find("C_DyeColor"),
    "expected conflict error mentioning C_DyeColor; got: " .. tostring(conflictErr))
print("  [OK] duplicate namespace claim is detected loud")

-- Clean up the rogue module so subsequent tests aren't affected (registry is
-- shared across dofile-included files; not strictly necessary because each
-- test file is its own Lua process, but explicit is safer).
VDS.Modules._registry["RogueObserver"] = nil

print("test_module_ownership.lua passed")
