--[[
    Core/Init.lua

    Start-up sequence. Must be the last file listed in the TOC so that every
    module has already registered itself by the time this runs.

    Two stages, matching what the client guarantees:

      ADDON_LOADED (ours)  -> saved variables exist   -> module:OnInitialize()
      PLAYER_LOGIN         -> world and UI are ready  -> module:OnEnable()

    Each call is guarded: a module that throws reports the error loudly through
    the debug channel, and the remaining modules still start. Silently
    swallowing the error would be worse than the crash it prevents.
]]

local addonName, ns = ...

local function CallSafely(module, methodName)
    local method = module[methodName]
    if type(method) ~= "function" then
        return
    end

    local ok, err = pcall(method, module)
    if not ok then
        ns.Debug:ReportError(("%s:%s"):format(module.moduleName, methodName), err)
    end
end

local function Initialize()
    ns.ForEachModule(function(module)
        CallSafely(module, "OnInitialize")
    end)

    ns.Debug:Log("INIT", "%s %s initialized", addonName, ns.version)
end

local function Enable()
    local _, classToken = UnitClass("player")
    ns.playerIsHunter = classToken == "HUNTER"

    ns.ForEachModule(function(module)
        CallSafely(module, "OnEnable")
    end)

    ns.Debug:Log("INIT", "enabled (player class: %s)", tostring(classToken))
    if not ns.playerIsHunter then
        ns.Debug:Log("INIT", "non-hunter character: stable features stay disabled")
    end
end

ns.Events:RegisterEvent("ADDON_LOADED", "Core.Init", function(_, loadedAddon)
    if loadedAddon ~= addonName then
        return
    end

    ns.Events:UnregisterEvent("ADDON_LOADED", "Core.Init")
    Initialize()
end)

ns.Events:RegisterEvent("PLAYER_LOGIN", "Core.Init", function()
    ns.Events:UnregisterEvent("PLAYER_LOGIN", "Core.Init")
    Enable()
end)
