local addonName, ApiVault = ...
ApiVault = ApiVault or {}
_G.ApiVault = ApiVault

ApiVault.name = addonName
ApiVault.version = "1.1.1"
ApiVault.interface = 120007
ApiVault.sourceInterfaceLabel = "12007"

function ApiVault:Print(message)
	DEFAULT_CHAT_FRAME:AddMessage("|cff66ccffApiVault|r: " .. tostring(message))
end

function ApiVault:StringTrim(value)
	value = tostring(value or "")
	return (value:gsub("^%s+", ""):gsub("%s+$", ""))
end

function ApiVault:StringLower(value)
	return string.lower(tostring(value or ""))
end

function ApiVault:Contains(haystack, needle)
	haystack = self:StringLower(haystack)
	needle = self:StringLower(needle)
	return needle == "" or string.find(haystack, needle, 1, true) ~= nil
end

function ApiVault:ShallowCopy(source)
	local copy = {}
	if type(source) == "table" then
		for key, value in pairs(source) do
			copy[key] = value
		end
	end
	return copy
end

function ApiVault:ResolveGlobal(path)
	local current = _G
	for part in string.gmatch(tostring(path or ""), "[^%.]+") do
		if type(current) ~= "table" then
			return nil
		end
		current = current[part]
		if current == nil then
			return nil
		end
	end
	return current
end

function ApiVault:Serialize(value, depth, visited)
	depth = depth or 0
	visited = visited or {}
	local valueType = type(value)
	if valueType == "string" then
		return string.format("%q", value)
	elseif valueType == "number" or valueType == "boolean" or valueType == "nil" then
		return tostring(value)
	elseif valueType == "function" then
		return "<function>"
	elseif valueType ~= "table" then
		return "<" .. valueType .. ">"
	end

	if visited[value] then
		return "<recursive table>"
	end
	if depth >= 3 then
		return "<table max-depth>"
	end

	visited[value] = true
	local parts = {"{"}
	local count = 0
	for key, child in pairs(value) do
		count = count + 1
		if count > 30 then
			table.insert(parts, " ...")
			break
		end
		table.insert(parts, " [" .. self:Serialize(key, depth + 1, visited) .. "] = " .. self:Serialize(child, depth + 1, visited) .. ",")
	end
	table.insert(parts, " }")
	visited[value] = nil
	return table.concat(parts, "")
end

function ApiVault:DocToText(value, depth)
	depth = depth or 0
	if value == nil then
		return ""
	end
	if type(value) == "string" or type(value) == "number" or type(value) == "boolean" then
		return tostring(value)
	end
	if type(value) ~= "table" then
		return ""
	end
	if depth > 3 then
		return ""
	end
	local lines = {}
	for _, child in ipairs(value) do
		local text = self:DocToText(child, depth + 1)
		if text ~= "" then
			table.insert(lines, text)
		end
	end
	return table.concat(lines, "\n")
end

function ApiVault:IsParamNilable(param)
	return param and (param.nilable or param.Nilable or param["nil"])
end

function ApiVault:FormatParam(param)
	if not param then
		return ""
	end
	local name = param.n or param.Name or "value"
	local valueType = param.t or param.Type or "unknown"
	local suffix = self:IsParamNilable(param) and "?" or ""
	local default = param.def or param.Default
	if default ~= nil then
		return name .. ": " .. valueType .. suffix .. " = " .. tostring(default)
	end
	return name .. ": " .. valueType .. suffix
end

function ApiVault:AppendLine(target, line)
	if target == nil or target == "" then
		return tostring(line or "")
	end
	return target .. "\n" .. tostring(line or "")
end
