local OFGGSCasingDisablePatch = {
    patched = false,
    hasDebugStackInfo = type(debug) == "table" and type(debug.getinfo) == "function",
}

local BLOCKED_GGS_CASING_TYPES = {
    ["Base.pistol_casing"] = true,
    ["Base.revolver_casing"] = true,
    ["Base.rifle_casing"] = true,
    ["Base.shells_casing"] = true,
}

local function isGgsShellEmitterCall()
    if not OFGGSCasingDisablePatch.hasDebugStackInfo then
        return false
    end

    for stackLevel = 3, 10 do
        local info = debug.getinfo(stackLevel, "S")
        if not info then
            break
        end

        local source = info.source
        if type(source) == "string" and string.find(source, "GGS_ShellCasingEmitter.lua", 1, true) then
            return true
        end
    end

    return false
end

local function isPatchToggleEnabled()
    local vars = SandboxVars and SandboxVars.OpinionatedFirearms
    if vars and vars.HandleHotBrassCasingSpawnUseAmmoMaker ~= nil then
        return vars.HandleHotBrassCasingSpawnUseAmmoMaker == true
    end

    -- Backward compatibility for existing worlds.
    if vars and vars.HBVCEFAmmoMakerPatch ~= nil then
        return vars.HBVCEFAmmoMakerPatch == true
    end

    return true
end

local function applyPatch()
    if OFGGSCasingDisablePatch.patched then
        return true
    end

    if not isPatchToggleEnabled() then
        OFGGSCasingDisablePatch.patched = true
        return true
    end

    if type(__classmetatables) ~= "table" then
        return false
    end

    if not zombie or not zombie.iso or not zombie.iso.IsoGridSquare or not zombie.iso.IsoGridSquare.class then
        return false
    end

    local squareMetatable = __classmetatables[zombie.iso.IsoGridSquare.class]
    if not squareMetatable or type(squareMetatable.__index) ~= "table" then
        return false
    end

    local originalAddWorldInventoryItem = squareMetatable.__index.AddWorldInventoryItem
    if type(originalAddWorldInventoryItem) ~= "function" then
        return false
    end

    squareMetatable.__index.AddWorldInventoryItem = function(square, itemType, ...)
        if BLOCKED_GGS_CASING_TYPES[itemType] and
            (not OFGGSCasingDisablePatch.hasDebugStackInfo or isGgsShellEmitterCall())
        then
            return nil
        end

        return originalAddWorldInventoryItem(square, itemType, ...)
    end

    OFGGSCasingDisablePatch.patched = true
    return true
end

local function tryPatchOnTick()
    if applyPatch() then
        Events.OnTick.Remove(tryPatchOnTick)
    end
end

if not applyPatch() then
    Events.OnTick.Add(tryPatchOnTick)
end
