-- ApiVault Secure Pattern Reference Index runtime helpers. Generated for ApiVault v0.2.7.
-- Compact metadata only. No bundled Blizzard source is read, displayed or executed at runtime.
local addonName, ApiVault = ...

ApiVault.SecurePatterns = ApiVault.SecurePatterns or {}
local Secure = ApiVault.SecurePatterns

Secure.entries = Secure.entries or {}
Secure.byFile = Secure.byFile or {}
Secure.byAPI = Secure.byAPI or {}
Secure.byTemplate = Secure.byTemplate or {}
Secure.byModule = Secure.byModule or {}
Secure.byRisk = Secure.byRisk or {}
Secure.metadata = {
	combat_sensitive_entries = 25,
	generated_at = "2026-06-28T13:51:46.051361+00:00",
	hardware_event_required_entries = 17,
	interface = 120007,
	metadata_only_entries = 18,
	module_entries = 53,
	pattern_counts = {
		["CreateFrame secure template"] = 3,
		GetAttribute = 237,
		InCombatLockdown = 19,
		OnAttributeChanged = 68,
		RegisterStateDriver = 3,
		SecretArguments = 3593,
		SecureActionButtonTemplate = 5,
		SecureAuraHeaderTemplate = 1,
		SecureFrameTemplate = 78,
		SecureHandlerTemplate = 17,
		SecureUnitButtonTemplate = 12,
		SetAttribute = 311,
		["TOC secure/useSecureEnvironment metadata"] = 18,
		UnregisterStateDriver = 3,
		UnwrapScript = 4,
		WrapScript = 4,
		hooksecurefunc = 14,
		["restricted/secret API metadata"] = 2,
		["sec=NotAllowed"] = 84,
	},
	pattern_entries = 4476,
	policy = "generated metadata only; inspect-only; no protected/secure execution; no runtime file reads",
	protected_entries = 84,
	resource_root = "Interface/AddOns/ApiVault/Examples/Interface",
	review_required_entries = 14,
	secure_sensitive_entries = 4318,
	source_archive = "Interface.zip",
	source_sha256 = "e04620731330f6c61c16f735ecba4ff550f7ad1baaf9912b6f8715a965ff0055",
	target_package = "ApiVault-v0.2.6.zip",
	target_sha256 = "e8d59913ccddd10cbf5b0a7cf8e665ee02c5d190d670d443d7ed6388a753bd72",
	type_counts = {
		["api-metadata"] = 3679,
		["combat-lockdown"] = 19,
		hook = 14,
		["secure-attribute"] = 616,
		["secure-createframe"] = 3,
		["secure-handler"] = 8,
		["secure-template"] = 113,
		["state-driver"] = 6,
		["toc-metadata"] = 18,
	},
	version = "0.2.7",
}

local function lower(value)
	return string.lower(tostring(value or ""))
end

local function contains(haystack, needle)
	haystack = lower(haystack)
	needle = lower(needle)
	return needle == "" or string.find(haystack, needle, 1, true) ~= nil
end

local function addToBucket(bucket, key, entry)
	if key == nil or key == "" then
		return
	end
	bucket[key] = bucket[key] or {}
	table.insert(bucket[key], entry)
end

function Secure:RegisterShard(shard)
	if type(shard) ~= "table" then
		return
	end
	for _, entry in ipairs(shard) do
		table.insert(self.entries, entry)
		addToBucket(self.byFile, entry.sourcePath, entry)
		addToBucket(self.byFile, entry.addonPath, entry)
		addToBucket(self.byAPI, entry.linkedAPI, entry)
		addToBucket(self.byTemplate, entry.linkedTemplate, entry)
		addToBucket(self.byModule, entry.module, entry)
		addToBucket(self.byModule, entry.linkedModule, entry)
		addToBucket(self.byRisk, entry.riskClass, entry)
	end
end

function Secure:GetStats()
	local meta = self.metadata or {}
	return meta.pattern_entries or #(self.entries or {}), meta.protected_entries or 0, meta.secure_sensitive_entries or 0, meta.combat_sensitive_entries or 0, meta.metadata_only_entries or 0
end

function Secure:GetForFile(path, limit)
	local list = (self.byFile and self.byFile[path]) or {}
	return self:LimitList(list, limit)
end

function Secure:GetForAPI(name, limit)
	local list = (self.byAPI and self.byAPI[name]) or {}
	return self:LimitList(list, limit)
end

function Secure:GetForTemplate(name, limit)
	local list = (self.byTemplate and self.byTemplate[name]) or {}
	return self:LimitList(list, limit)
end

function Secure:GetForModule(name, limit)
	local list = (self.byModule and self.byModule[name]) or {}
	return self:LimitList(list, limit)
end

function Secure:LimitList(list, limit)
	if type(list) ~= "table" then
		return {}
	end
	limit = limit or #list
	local out = {}
	for index, entry in ipairs(list) do
		if index > limit then break end
		out[#out + 1] = entry
	end
	return out
end

function Secure:GetAutoRunPolicyForAPI(name)
	local list = self:GetForAPI(name)
	local policy = nil
	local reason = nil
	for _, entry in ipairs(list or {}) do
		if entry.autoRunPolicy == "blocked" or entry.riskClass == "protected" then
			return "blocked", tostring(entry.patternName or "secure pattern")
		elseif not policy and entry.autoRunPolicy then
			policy = entry.autoRunPolicy
			reason = tostring(entry.patternName or "secure pattern")
		end
	end
	return policy, reason
end

function Secure:IsBlockedAPI(name)
	local policy, reason = self:GetAutoRunPolicyForAPI(name)
	if policy == "blocked" then
		return true, reason or "secure pattern blocks auto-run"
	end
	return false, reason
end

function Secure:Search(query, filter, limit)
	query = lower(query)
	filter = filter or "All"
	limit = limit or 300
	local results = {}
	for _, entry in ipairs(self.entries or {}) do
		local include = false
		if filter == "All" then
			include = true
		elseif filter == "Protected" then
			include = entry.riskClass == "protected"
		elseif filter == "SecureSensitive" then
			include = entry.riskClass == "secure-sensitive"
		elseif filter == "Combat" then
			include = entry.riskClass == "combat-sensitive"
		elseif filter == "Metadata" then
			include = entry.riskClass == "metadata-only"
		elseif filter == "Templates" then
			include = entry.patternType == "secure-template" or entry.patternType == "secure-createframe"
		elseif filter == "API" then
			include = entry.patternType == "api-metadata" or (entry.linkedAPI and entry.linkedAPI ~= "")
		elseif filter == "TOC" then
			include = entry.patternType == "toc-metadata"
		elseif filter == "Hooks" then
			include = entry.patternName == "hooksecurefunc"
		else
			include = true
		end
		if include then
			local haystack = tostring(entry.patternName or "") .. " " .. tostring(entry.patternType or "") .. " " .. tostring(entry.riskClass or "") .. " " .. tostring(entry.sourcePath or "") .. " " .. tostring(entry.addonPath or "") .. " " .. tostring(entry.module or "") .. " " .. tostring(entry.contextLabel or "") .. " " .. tostring(entry.linkedAPI or "") .. " " .. tostring(entry.linkedTemplate or "")
			if contains(haystack, query) then
				table.insert(results, { kind = "SecurePattern", data = entry, display = tostring(entry.patternName or "?") .. " / " .. tostring(entry.module or "?") })
				if #results >= limit then return results end
			end
		end
	end
	return results
end

function Secure:DescribePattern(entryOrResult)
	local entry = entryOrResult and (entryOrResult.data or entryOrResult) or nil
	if not entry then
		return "No secure pattern selected."
	end
	local lines = {}
	table.insert(lines, "Secure pattern metadata")
	table.insert(lines, "patternId: " .. tostring(entry.patternId or "?"))
	table.insert(lines, "patternName: " .. tostring(entry.patternName or "?"))
	table.insert(lines, "patternType: " .. tostring(entry.patternType or "?"))
	table.insert(lines, "riskClass: " .. tostring(entry.riskClass or "?"))
	table.insert(lines, "autoRunPolicy: " .. tostring(entry.autoRunPolicy or "inspect-only"))
	table.insert(lines, "module: " .. tostring(entry.module or "?"))
	table.insert(lines, "fileType: " .. tostring(entry.fileType or "?"))
	table.insert(lines, "sourcePath: " .. tostring(entry.sourcePath or "?"))
	table.insert(lines, "addonPath: " .. tostring(entry.addonPath or "?"))
	table.insert(lines, "line: " .. tostring(entry.line or "?"))
	table.insert(lines, "contextLabel: " .. tostring(entry.contextLabel or ""))
	if entry.linkedAPI and entry.linkedAPI ~= "" then
		table.insert(lines, "linkedAPI: " .. tostring(entry.linkedAPI))
	end
	if entry.linkedTemplate and entry.linkedTemplate ~= "" then
		table.insert(lines, "linkedTemplate: " .. tostring(entry.linkedTemplate))
	end
	if entry.linkedModule and entry.linkedModule ~= "" then
		table.insert(lines, "linkedModule: " .. tostring(entry.linkedModule))
	end
	table.insert(lines, "")
	table.insert(lines, "Notes:")
	table.insert(lines, tostring(entry.notes or "Inspect-only secure reference metadata."))
	table.insert(lines, "")
	table.insert(lines, "Uncertain behavior:")
	table.insert(lines, tostring(entry.uncertainNotes or "UNCERTAIN"))
	table.insert(lines, "")
	table.insert(lines, "Policy: inspect-only. ApiVault does not execute protected, secure or combat-sensitive patterns.")
	if ApiVault.ExampleSecureLinks and ApiVault.ExampleSecureLinks.AppendSecurePatternLinks then
		lines = { ApiVault.ExampleSecureLinks:AppendSecurePatternLinks(table.concat(lines, "\n"), entry, 5) }
	end
	return table.concat(lines, "\n")
end

local function appendEntryLines(text, entries, limit)
	limit = limit or 5
	if type(entries) ~= "table" or #entries == 0 then
		return ApiVault:AppendLine(text, "- no secure pattern references indexed")
	end
	for index, entry in ipairs(entries) do
		if index > limit then
			text = ApiVault:AppendLine(text, "- ... +" .. tostring(#entries - limit) .. " more")
			break
		end
		text = ApiVault:AppendLine(text, "  " .. tostring(index) .. ". " .. tostring(entry.patternName or "?") .. " / " .. tostring(entry.riskClass or "?") .. " / " .. tostring(entry.autoRunPolicy or "inspect-only"))
		text = ApiVault:AppendLine(text, "     " .. tostring(entry.addonPath or entry.sourcePath or "?") .. ":" .. tostring(entry.line or "?") .. " [" .. tostring(entry.module or "?") .. "] " .. tostring(entry.contextLabel or ""))
	end
	return text
end

function Secure:AppendOwnerSummary(text, ownerName, ownerType, limit)
	local entries = {}
	if ownerType == "Function" or ownerType == "function" or ownerType == "API" then
		entries = self:GetForAPI(ownerName, limit or 5)
	elseif ownerType == "Template" or ownerType == "XMLTemplate" then
		entries = self:GetForTemplate(ownerName, limit or 5)
	elseif ownerType == "Module" then
		entries = self:GetForModule(ownerName, limit or 5)
	elseif ownerType == "File" then
		entries = self:GetForFile(ownerName, limit or 5)
	end
	text = ApiVault:AppendLine(text, "")
	text = ApiVault:AppendLine(text, "Secure pattern references:")
	text = ApiVault:AppendLine(text, "- policy: INSPECT_ONLY; no protected or secure execution")
	return appendEntryLines(text, entries, limit or 5)
end

function Secure:AppendFileSummary(text, sourcePath, limit)
	text = ApiVault:AppendLine(text, "")
	text = ApiVault:AppendLine(text, "Secure pattern references for file:")
	text = ApiVault:AppendLine(text, "- policy: INSPECT_ONLY; no protected/secure execution")
	return appendEntryLines(text, self:GetForFile(sourcePath, limit or 5), limit or 5)
end

function Secure:AppendTemplateSummary(text, templateName, sourcePath, limit)
	local entries = self:GetForTemplate(templateName, limit or 5)
	if #entries == 0 and sourcePath then
		entries = self:GetForFile(sourcePath, limit or 5)
	end
	text = ApiVault:AppendLine(text, "")
	text = ApiVault:AppendLine(text, "Secure pattern references for template:")
	text = ApiVault:AppendLine(text, "- policy: INSPECT_ONLY; no protected/secure execution")
	return appendEntryLines(text, entries, limit or 5)
end

function Secure:AppendModuleSummaryText(text, moduleName, limit)
	text = ApiVault:AppendLine(text, "")
	text = ApiVault:AppendLine(text, "Secure pattern references for module:")
	text = ApiVault:AppendLine(text, "- policy: INSPECT_ONLY; no protected/secure execution")
	return appendEntryLines(text, self:GetForModule(moduleName, limit or 8), limit or 8)
end

function Secure:AppendExampleSummary(text, example, limit)
	if type(example) ~= "table" then
		return text
	end
	local entries = {}
	if example.ownerName then
		entries = self:GetForAPI(example.ownerName, limit or 5)
	end
	if #entries == 0 and example.sourcePath then
		entries = self:GetForFile(example.sourcePath, limit or 5)
	end
	text = ApiVault:AppendLine(text, "")
	text = ApiVault:AppendLine(text, "Related secure pattern references:")
	text = ApiVault:AppendLine(text, "- policy: INSPECT_ONLY; no protected/secure execution")
	return appendEntryLines(text, entries, limit or 5)
end
