---
-- XMLWrapManager
--
--
-- @author      nilBrain
-- @date        2026-01-08
--
-- Copyright (C) nilBrain | Philipp Jaeger, Confidential, All Rights Reserved.

if _G.g_iconGenerator ~= nil then
    return
end

local globalEnv = getmetatable(_G).__index

if globalEnv.XMLFile.WRAP_INJECTIONS ~= nil then
    return
end

local modDirectory = g_currentModDirectory

---Loads wrap injection mappings from this mod's modDesc.xml into the global registry
local function loadFromModDesc()
    local modDesc = XMLFile.load("tempModDesc", modDirectory .. "modDesc.xml")
    if modDesc == nil then
        return
    end

    for _, key in modDesc:iterator("modDesc.xmlWraps.wrap") do
        local filename = modDesc:getString(key .. "#filename")
        local injectXMLFilename = modDesc:getString(key .. "#injectXMLFilename")

        if string.isNilOrWhitespace(filename) or string.isNilOrWhitespace(injectXMLFilename) then
            Logging.xmlWarning(modDesc, "Invalid filename in %s", modDesc:getLineNumber(key))
            continue
        end

        globalEnv.XMLFile.WRAP_INJECTIONS[filename] = NetworkUtil.convertFromNetworkFilename(injectXMLFilename)
    end

    modDesc:delete()
end

---Applies the wrap-injection rules from the given inject XML to the target XML file
-- @param string injectXMLFilename inject XML file name relative to mod directory
-- @param XMLFile xmlFile target XML file being loaded
local function customXMLInjection(injectXMLFilename, xmlFile)
    local injectXML = loadXMLFile(xmlFile.objectName, Utils.getFilename(injectXMLFilename, modDirectory))
    if injectXML == 0 then
        return
    end

    local i = 0
    while true do
        local key = string.format("wrap.attributes.remove(%d)", i)
        if not hasXMLProperty(injectXML, key) then
            break
        end

        local path = getXMLString(injectXML, key .. "#path")
        xmlFile:removeProperty(path)

        i = i + 1
    end

    i = 0
    while true do
        local key = string.format("wrap.attributes.set(%d)", i)
        if not hasXMLProperty(injectXML, key) then
            break
        end

        local path = getXMLString(injectXML, key .. "#path")
        local value = getXMLString(injectXML, key .. "#value")
        xmlFile:setString(path, value)

        i = i + 1
    end

    delete(injectXML)
end

local oldXMLFileNew = globalEnv.XMLFile.new

---Patched XMLFile.new that triggers wrap injection for registered filenames
-- @param string objectName object name
-- @param string filename xml filename
-- @param integer handle xml handle
-- @param XMLSchema schema xml schema
-- @return XMLFile newFile newly created xml file
function globalEnv.XMLFile.new(objectName, filename, handle, schema)
    local newFile = oldXMLFileNew(objectName, filename, handle, schema)
    local injectXMLFilename = globalEnv.XMLFile.WRAP_INJECTIONS[filename]

    if not string.isNilOrWhitespace(injectXMLFilename) then
        customXMLInjection(injectXMLFilename, newFile)
    end

    return newFile
end

---Initializes the wrap injection registry and loads mappings from modDesc
local function init()
    globalEnv.XMLFile.WRAP_INJECTIONS = {}
    loadFromModDesc()
end

init()
