local addonName, ApiVault = ...

ApiVault.frame = CreateFrame("Frame")

function ApiVault:InitDatabase()
	ApiVaultDB = ApiVaultDB or {}
	ApiVaultDB.recent = ApiVaultDB.recent or {}
	ApiVaultDB.favorites = ApiVaultDB.favorites or {}
	ApiVaultDB.settings = ApiVaultDB.settings or {}
	if ApiVaultDB.settings.allowRestrictedExecution == nil then
		ApiVaultDB.settings.allowRestrictedExecution = false
	end
	if self.UserState and self.UserState.Validate then
		self.UserState:Validate()
	end
	self.db = ApiVaultDB
end

function ApiVault:GetClientBuildText()
	if type(GetBuildInfo) ~= "function" then
		return "GetBuildInfo unavailable"
	end
	local buildVersion, buildNumber, buildDate, interfaceVersion, localizedVersion = GetBuildInfo()
	return tostring(buildVersion) .. " / build " .. tostring(buildNumber) .. " / interface " .. tostring(interfaceVersion) .. " / date " .. tostring(buildDate) .. " / localized " .. tostring(localizedVersion)
end

function ApiVault:Init()
	self:InitDatabase()
	self.loaded = true
	self:Print("loaded v" .. tostring(self.version) .. ". Use /apivault or /av.")
	self:Print("client: " .. self:GetClientBuildText())
end

function ApiVault:Slash(message)
	message = self:StringTrim(message)
	if message == "stats" then
		local meta = self.APIData and self.APIData.metadata or {}
		local usageText = ""
		if self.SourceUsage and self.SourceUsage.GetStats then
			local apiUsage, eventUsage, moduleUsage = self.SourceUsage:GetStats()
			usageText = ", sourceUsage APIs=" .. tostring(apiUsage) .. ", events=" .. tostring(eventUsage) .. ", modules=" .. tostring(moduleUsage)
		end
		if self.InterfaceResources and self.InterfaceResources.GetStats then
			local files, folders, modules = self.InterfaceResources:GetStats()
			usageText = usageText .. ", resources files=" .. tostring(files) .. ", folders=" .. tostring(folders) .. ", modules=" .. tostring(modules)
		end
		if self.XMLCatalog and self.XMLCatalog.GetStats then
			local templates, xmlFiles, virtualTemplates, secureTemplates = self.XMLCatalog:GetStats()
			usageText = usageText .. ", xmlTemplates=" .. tostring(templates) .. ", xmlFiles=" .. tostring(xmlFiles) .. ", virtual=" .. tostring(virtualTemplates) .. ", secureRefs=" .. tostring(secureTemplates)
		end
		if self.ModuleCatalog and self.ModuleCatalog.GetStats then
			local tocEntries, moduleEntries, tocFileRefs = self.ModuleCatalog:GetStats()
			usageText = usageText .. ", moduleTOCs=" .. tostring(tocEntries) .. ", modules=" .. tostring(moduleEntries) .. ", tocFileRefs=" .. tostring(tocFileRefs)
		end
		if self.SourceExamples and self.SourceExamples.GetStats then
			local examples, apiExamples, eventExamples = self.SourceExamples:GetStats()
			usageText = usageText .. ", sourceExamples=" .. tostring(examples) .. ", apiExamples=" .. tostring(apiExamples) .. ", eventExamples=" .. tostring(eventExamples)
		end
		if self.SecurePatterns and self.SecurePatterns.GetStats then
			local secureTotal, protectedCount, secureSensitive, combatSensitive, metadataOnly = self.SecurePatterns:GetStats()
			usageText = usageText .. ", securePatterns=" .. tostring(secureTotal) .. ", protected=" .. tostring(protectedCount) .. ", secureSensitive=" .. tostring(secureSensitive) .. ", combatSensitive=" .. tostring(combatSensitive)
		end
		if self.GlobalSearch and self.GlobalSearch.GetStats then
			local layers = self.GlobalSearch:GetStats()
			usageText = usageText .. ", searchLayers=" .. tostring(layers)
		end
		if self.ResourceLinks and self.ResourceLinks.GetStats then
			local linkLayers = self.ResourceLinks:GetStats()
			usageText = usageText .. ", crossLinkLayers=" .. tostring(linkLayers)
		end
		if self.ExampleSecureLinks and self.ExampleSecureLinks.GetStats then
			local polishLayers = self.ExampleSecureLinks:GetStats()
			usageText = usageText .. ", exampleSecureLinkLayers=" .. tostring(polishLayers)
		end
		if self.ChecklistExport and self.ChecklistExport.GetStats then
			local exportBuilders = self.ChecklistExport:GetStats()
			usageText = usageText .. ", exportBuilders=" .. tostring(exportBuilders)
		end
		if self.UserState and self.UserState.GetStats then
			local favorites, recentItems, recentSearches = self.UserState:GetStats()
			usageText = usageText .. ", favorites=" .. tostring(favorites) .. ", recentItems=" .. tostring(recentItems) .. ", recentSearches=" .. tostring(recentSearches)
		end
		if self.TestHistory and self.TestHistory.GetStats then
			local testHistory, lastBlocked = self.TestHistory:GetStats()
			usageText = usageText .. ", testHistory=" .. tostring(testHistory) .. ", lastBlocked=" .. tostring(lastBlocked)
		end
		if self.Symbols and self.Symbols.GetStats then
			local symbols, documentedSymbols, mixinSymbols, xmlScriptSymbols, slashSymbols = self.Symbols:GetStats()
			usageText = usageText .. ", symbols=" .. tostring(symbols) .. ", documentedSymbols=" .. tostring(documentedSymbols) .. ", mixins=" .. tostring(mixinSymbols) .. ", xmlScripts=" .. tostring(xmlScriptSymbols) .. ", slashSymbols=" .. tostring(slashSymbols)
		end
		if self.GlobalInspector and self.GlobalInspector.GetStats then
			local cachedGlobals, scannedGlobals, lastGlobalRefresh = self.GlobalInspector:GetStats()
			usageText = usageText .. ", runtimeGlobalsCached=" .. tostring(cachedGlobals) .. ", runtimeGlobalsScanned=" .. tostring(scannedGlobals)
		end
		if self.Catalogs and self.Catalogs.GetStats then
			local catalogTotal, constants, slash, bindings, settings = self.Catalogs:GetStats()
			usageText = usageText .. ", catalogs=" .. tostring(catalogTotal) .. ", constants=" .. tostring(constants) .. ", slashCatalog=" .. tostring(slash) .. ", bindings=" .. tostring(bindings) .. ", settings=" .. tostring(settings)
		end
		if self.Widgets and self.Widgets.GetStats then
			local widgetTotal, methods, scripts, createFrames, setScripts = self.Widgets:GetStats()
			usageText = usageText .. ", widgets=" .. tostring(widgetTotal) .. ", widgetMethods=" .. tostring(methods) .. ", widgetScripts=" .. tostring(scripts) .. ", createFrameRefs=" .. tostring(createFrames) .. ", setScriptRefs=" .. tostring(setScripts)
		end
		if self.AddonAudit and self.AddonAudit.GetStats then
			local auditRules, lastIssues, lastType = self.AddonAudit:GetStats()
			usageText = usageText .. ", addonAuditRules=" .. tostring(auditRules) .. ", lastAuditIssues=" .. tostring(lastIssues) .. ", lastAuditType=" .. tostring(lastType)
		end

		if self.DeveloperAPI and self.DeveloperAPI.GetStats then
			local devAddons, devLogs, devErrors, devAPITraces, devEventTraces, devSecureRisks = self.DeveloperAPI:GetStats()
			usageText = usageText .. ", devAPIAddons=" .. tostring(devAddons) .. ", devLogs=" .. tostring(devLogs) .. ", devErrors=" .. tostring(devErrors) .. ", devAPITraces=" .. tostring(devAPITraces) .. ", devEventTraces=" .. tostring(devEventTraces) .. ", devSecureRisks=" .. tostring(devSecureRisks)
		end
		if self.BugAdvisor and self.BugAdvisor.GetStats then
			local bugCategories, bugSecurePatterns = self.BugAdvisor:GetStats()
			usageText = usageText .. ", bugAdvisorCategories=" .. tostring(bugCategories) .. ", bugAdvisorSecurePatterns=" .. tostring(bugSecurePatterns)
		end

		if self.LoadedAddonInspector and self.LoadedAddonInspector.GetStats then
			local loadedAddons, loadedRefresh = self.LoadedAddonInspector:GetStats()
			usageText = usageText .. ", loadedAddonsCached=" .. tostring(loadedAddons) .. ", loadedAddonRefresh=" .. tostring(loadedRefresh)
		end
		if self.EventRecorder and self.EventRecorder.GetStats then
			local activeEvents, eventHistory, eventHistoryMax = self.EventRecorder:GetStats()
			usageText = usageText .. ", eventLabActive=" .. tostring(activeEvents) .. ", eventPayloads=" .. tostring(eventHistory)
		end
		if self.BuildDiff and self.BuildDiff.GetStats then
			local diffInterface, diffApis, diffXml, diffSymbols = self.BuildDiff:GetStats()
			usageText = usageText .. ", buildDiffInterface=" .. tostring(diffInterface) .. ", diffAPIs=" .. tostring(diffApis) .. ", diffXML=" .. tostring(diffXml) .. ", diffSymbols=" .. tostring(diffSymbols)
		end
		if self.StableRelease and self.StableRelease.GetStats then
			local releaseChecks, releaseVersion = self.StableRelease:GetStats()
			usageText = usageText .. ", releaseVersion=" .. tostring(releaseVersion) .. ", releaseChecks=" .. tostring(releaseChecks)
		end

		if self.TodoCompletion and self.TodoCompletion.GetStats then
			local todoGroups = self.TodoCompletion:GetStats()
			usageText = usageText .. ", todoPolishGroups=" .. tostring(todoGroups)
		end
		self:Print("docs=" .. tostring(meta.documentation_files) .. ", functions=" .. tostring(meta.functions) .. ", events=" .. tostring(meta.events) .. ", tables=" .. tostring(meta.tables) .. usageText)
		return
	elseif message == "compat" then
		self:Print("toc interface=" .. tostring(self.interface) .. "; source label=" .. tostring(self.sourceInterfaceLabel) .. "; client=" .. self:GetClientBuildText())
		return
	elseif message == "usage" then
		if self.SourceUsage and self.SourceUsage.GetStats then
			local apiUsage, eventUsage, moduleUsage = self.SourceUsage:GetStats()
			self:Print("source usage index: APIs=" .. tostring(apiUsage) .. ", events=" .. tostring(eventUsage) .. ", modules=" .. tostring(moduleUsage))
		else
			self:Print("source usage index unavailable.")
		end
		return
	elseif message == "interface" or message == "resources" then
		if self.InterfaceResources and self.InterfaceResources.GetStats then
			local files, folders, modules = self.InterfaceResources:GetStats()
			self:Print("interface resources: files=" .. tostring(files) .. ", folders=" .. tostring(folders) .. ", modules=" .. tostring(modules))
		end
		if self.InterfaceBrowser and self.InterfaceBrowser.Toggle then
			self.InterfaceBrowser:Toggle()
		else
			self:Print("interface browser unavailable.")
		end
		return
	elseif message == "templates" or message == "xml" then
		if self.XMLCatalog and self.XMLCatalog.GetStats then
			local templates, xmlFiles, virtualTemplates, secureTemplates = self.XMLCatalog:GetStats()
			self:Print("xml template catalog: templates=" .. tostring(templates) .. ", xmlFiles=" .. tostring(xmlFiles) .. ", virtual=" .. tostring(virtualTemplates) .. ", secureRefs=" .. tostring(secureTemplates))
		else
			self:Print("xml template catalog unavailable.")
		end
		if self.XMLTemplateBrowser and self.XMLTemplateBrowser.Toggle then
			self.XMLTemplateBrowser:Toggle()
		end
		return
	elseif message == "modules" or message == "toc" then
		if self.ModuleCatalog and self.ModuleCatalog.GetStats then
			local tocEntries, moduleEntries, tocFileRefs = self.ModuleCatalog:GetStats()
			self:Print("toc module catalog: TOCs=" .. tostring(tocEntries) .. ", modules=" .. tostring(moduleEntries) .. ", tocFileRefs=" .. tostring(tocFileRefs))
		else
			self:Print("toc module catalog unavailable.")
		end
		if self.ModuleBrowser and self.ModuleBrowser.Toggle then
			self.ModuleBrowser:Toggle()
		end
		return
	elseif message == "examples" then
		if self.SourceExamples and self.SourceExamples.GetStats then
			local examples, apiExamples, eventExamples = self.SourceExamples:GetStats()
			self:Print("source examples: total=" .. tostring(examples) .. ", APIs=" .. tostring(apiExamples) .. ", events=" .. tostring(eventExamples))
		else
			self:Print("source example index unavailable.")
		end
		if self.SourceExampleBrowser and self.SourceExampleBrowser.Toggle then
			self.SourceExampleBrowser:Toggle()
		end
		return
	elseif message == "secure" then
		if self.SecurePatterns and self.SecurePatterns.GetStats then
			local secureTotal, protectedCount, secureSensitive, combatSensitive, metadataOnly = self.SecurePatterns:GetStats()
			self:Print("secure pattern index: total=" .. tostring(secureTotal) .. ", protected=" .. tostring(protectedCount) .. ", secureSensitive=" .. tostring(secureSensitive) .. ", combatSensitive=" .. tostring(combatSensitive) .. ", metadataOnly=" .. tostring(metadataOnly))
		else
			self:Print("secure pattern index unavailable.")
		end
		if self.SecurePatternBrowser and self.SecurePatternBrowser.Toggle then
			self.SecurePatternBrowser:Toggle()
		end
		return
	elseif message == "search" or message == "global" then
		if self.GlobalSearch and self.GlobalSearch.GetStats then
			local layers, counts = self.GlobalSearch:GetStats()
			self:Print("global search: layers=" .. tostring(layers) .. ", resources=" .. tostring(counts.resourceFiles or 0) .. ", xmlTemplates=" .. tostring(counts.xmlTemplates or 0) .. ", modules=" .. tostring(counts.moduleTOCs or 0) .. ", examples=" .. tostring(counts.sourceExamples or 0) .. ", secure=" .. tostring(counts.securePatterns or 0) .. ", symbols=" .. tostring(counts.symbols or 0))
		else
			self:Print("global search unavailable.")
		end
		if self.UnifiedSearch and self.UnifiedSearch.Toggle then
			self.UnifiedSearch:Toggle()
		end
		return
	elseif message == "export" or message == "checklist" or message == "checklists" then
		if self.ChecklistExport and self.ChecklistExport.GetStats then
			local builders, label = self.ChecklistExport:GetStats()
			self:Print("developer export panels: builders=" .. tostring(builders) .. ", " .. tostring(label))
		else
			self:Print("developer export panels unavailable.")
		end
		if self.ExportPanel and self.ExportPanel.Toggle then
			self.ExportPanel:Toggle()
		else
			self:Print("export panel unavailable.")
		end
		return
	elseif message == "favorites" or message == "favs" or message == "recent" or message == "history" then
		if self.UserState and self.UserState.GetStats then
			local favorites, recentItems, recentSearches = self.UserState:GetStats()
			self:Print("favorites/recent: favorites=" .. tostring(favorites) .. ", recentItems=" .. tostring(recentItems) .. ", recentSearches=" .. tostring(recentSearches))
		else
			self:Print("favorites/recent unavailable.")
		end
		if self.FavoritesRecentPanel and self.FavoritesRecentPanel.Toggle then
			self.FavoritesRecentPanel:Toggle()
		else
			self:Print("favorites/recent panel unavailable.")
		end
		return
	elseif message == "testlab" or message == "tests" or message == "testhistory" or message == "runtime" or message == "lab" then
		if self.TestHistory and self.TestHistory.GetStats then
			local testHistory, lastBlocked = self.TestHistory:GetStats()
			self:Print("runtime test lab: history=" .. tostring(testHistory) .. ", lastBlocked=" .. tostring(lastBlocked))
		else
			self:Print("runtime test lab history unavailable.")
		end
		if self.TestLabPanel and self.TestLabPanel.Toggle then
			self.TestLabPanel:Toggle()
		else
			self:Print("runtime test lab panel unavailable.")
		end
		return
	elseif message == "links" or message == "crosslinks" then
		if self.ResourceLinks and self.ResourceLinks.GetStats then
			local linkLayers, label = self.ResourceLinks:GetStats()
			self:Print("cross-links: layers=" .. tostring(linkLayers) .. ", " .. tostring(label))
		else
			self:Print("resource cross-links unavailable.")
		end
		if self.ExampleSecureLinks and self.ExampleSecureLinks.GetStats then
			local polishLayers, polishLabel = self.ExampleSecureLinks:GetStats()
			self:Print("example/secure polish: layers=" .. tostring(polishLayers) .. ", " .. tostring(polishLabel))
		end
		return
	elseif message == "symbols" or message == "symbol" then
		if self.Symbols and self.Symbols.GetStats then
			local symbols, documentedSymbols, mixinSymbols, xmlScriptSymbols, slashSymbols = self.Symbols:GetStats()
			self:Print("symbol catalog: symbols=" .. tostring(symbols) .. ", documentedAPIs=" .. tostring(documentedSymbols) .. ", mixins=" .. tostring(mixinSymbols) .. ", xmlScripts=" .. tostring(xmlScriptSymbols) .. ", slash=" .. tostring(slashSymbols))
		else
			self:Print("symbol catalog unavailable.")
		end
		if self.SymbolBrowser and self.SymbolBrowser.Toggle then
			self.SymbolBrowser:Toggle()
		else
			self:Print("symbol browser unavailable.")
		end
		return
	elseif message == "globals" or message == "globalinspector" then
		if self.GlobalInspector and self.GlobalInspector.GetStats then
			local cachedGlobals, scannedGlobals, lastGlobalRefresh = self.GlobalInspector:GetStats()
			self:Print("runtime globals: cached=" .. tostring(cachedGlobals) .. ", scanned=" .. tostring(scannedGlobals) .. ", last=" .. tostring(lastGlobalRefresh))
		else
			self:Print("runtime global inspector unavailable.")
		end
		if self.RuntimeGlobalsPanel and self.RuntimeGlobalsPanel.Toggle then
			self.RuntimeGlobalsPanel:Toggle()
		else
			self:Print("runtime globals panel unavailable.")
		end
		return
	elseif message == "mixins" then
        if self.SymbolBrowser and self.SymbolBrowser.Toggle then
            self.SymbolBrowser:Toggle()
            if self.SymbolBrowser.frame then
                self.SymbolBrowser.filter = "Mixin"
                self.SymbolBrowser:Refresh()
            end
        else
            self:Print("symbol browser unavailable.")
        end
        return
    elseif message == "polish" or message == "todo" or message == "actions" then
        if self.TodoCompletion and self.TodoCompletion.GetStats then
            local groups, label = self.TodoCompletion:GetStats()
            self:Print("todo completion polish: groups=" .. tostring(groups) .. ", " .. tostring(label))
        else
            self:Print("todo completion polish unavailable.")
        end
        if self.TodoCompletionPanel and self.TodoCompletionPanel.Toggle then
            self.TodoCompletionPanel:Toggle()
        end
        return
    elseif message == "compact" then
        if self.TodoCompletion and self.TodoCompletion.SetCompactMode then
            local enabled = not self.TodoCompletion:IsCompactMode()
            self.TodoCompletion:SetCompactMode(enabled)
            self:Print("compact mode setting=" .. tostring(enabled) .. ". Reopen panels to apply where supported.")
        else
            self:Print("compact mode unavailable.")
        end
        return
	elseif message == "catalogs" or message == "catalog" then
		if self.Catalogs and self.Catalogs.GetStats then
			local catalogTotal, constants, slash, bindings, settings = self.Catalogs:GetStats()
			self:Print("catalogs: total=" .. tostring(catalogTotal) .. ", constants=" .. tostring(constants) .. ", slash=" .. tostring(slash) .. ", bindings=" .. tostring(bindings) .. ", settings=" .. tostring(settings))
		else
			self:Print("catalogs unavailable.")
		end
		if self.CatalogBrowser and self.CatalogBrowser.Open then self.CatalogBrowser:Open("All") end
		return
	elseif message == "constants" then
		if self.CatalogBrowser and self.CatalogBrowser.Open then self.CatalogBrowser:Open("Constants") else self:Print("catalog browser unavailable.") end
		return
	elseif message == "slash" or message == "slashes" then
		if self.CatalogBrowser and self.CatalogBrowser.Open then self.CatalogBrowser:Open("Slash") else self:Print("catalog browser unavailable.") end
		return
	elseif message == "bindings" or message == "binds" then
		if self.CatalogBrowser and self.CatalogBrowser.Open then self.CatalogBrowser:Open("Bindings") else self:Print("catalog browser unavailable.") end
		return
	elseif message == "settings" or message == "cvars" or message == "cvar" then
		if self.CatalogBrowser and self.CatalogBrowser.Open then self.CatalogBrowser:Open("Settings") else self:Print("catalog browser unavailable.") end
		return
	elseif message == "widgets" or message == "widget" or message == "frameapi" then
		if self.Widgets and self.Widgets.GetStats then
			local widgetTotal, methods, scripts, createFrames, setScripts = self.Widgets:GetStats()
			self:Print("widget catalog: total=" .. tostring(widgetTotal) .. ", methods=" .. tostring(methods) .. ", scripts=" .. tostring(scripts) .. ", createFrame=" .. tostring(createFrames) .. ", setScript=" .. tostring(setScripts))
		else
			self:Print("widget catalog unavailable.")
		end
		if self.WidgetMethodBrowser and self.WidgetMethodBrowser.Open then self.WidgetMethodBrowser:Open("All") end
		return
	elseif message == "scripts" or message == "scripthandlers" then
		if self.WidgetMethodBrowser and self.WidgetMethodBrowser.Open then self.WidgetMethodBrowser:Open("Scripts") else self:Print("widget method browser unavailable.") end
		return
	elseif message == "createframe" or message == "frames" then
		if self.WidgetMethodBrowser and self.WidgetMethodBrowser.Open then self.WidgetMethodBrowser:Open("CreateFrame") else self:Print("widget method browser unavailable.") end
		return
	elseif message == "scriptobjects" or message == "methods" then
		if self.WidgetMethodBrowser and self.WidgetMethodBrowser.Open then self.WidgetMethodBrowser:Open("Methods") else self:Print("widget method browser unavailable.") end
		return

	elseif message == "audit" or message == "scan" or message == "addoncheck" or message == "auditmode" then
		if self.AddonAudit and self.AddonAudit.GetStats then
			local auditRules, lastIssues, lastType = self.AddonAudit:GetStats()
			self:Print("addon audit mode: rules=" .. tostring(auditRules) .. ", lastIssues=" .. tostring(lastIssues) .. ", lastType=" .. tostring(lastType))
		else
			self:Print("addon audit rules unavailable.")
		end
		if self.AddonAuditPanel and self.AddonAuditPanel.Toggle then
			self.AddonAuditPanel:Toggle()
		else
			self:Print("addon audit panel unavailable.")
		end
		return

	elseif message == "devapi" or message == "debugbridge" or message == "addondebug" or message == "reports" or message == "bugadvisor" then
		if self.DeveloperAPI and self.DeveloperAPI.GetStats then
			local devAddons, devLogs, devErrors, devAPITraces, devEventTraces, devSecureRisks = self.DeveloperAPI:GetStats()
			self:Print("developer debug API: addons=" .. tostring(devAddons) .. ", logs=" .. tostring(devLogs) .. ", errors=" .. tostring(devErrors) .. ", apiTraces=" .. tostring(devAPITraces) .. ", eventTraces=" .. tostring(devEventTraces) .. ", secureRisks=" .. tostring(devSecureRisks))
		else
			self:Print("developer debug API unavailable.")
		end
		if self.DeveloperDebugPanel and self.DeveloperDebugPanel.Toggle then
			self.DeveloperDebugPanel:Toggle()
		else
			self:Print("developer debug panel unavailable.")
		end
		return

	elseif message == "addons" or message == "loaded" or message == "loadedaddons" then
		if self.LoadedAddonInspector and self.LoadedAddonInspector.Refresh then
			self.LoadedAddonInspector:Refresh()
			local loadedAddons, loadedRefresh = self.LoadedAddonInspector:GetStats()
			self:Print("loaded addon inspector: cached=" .. tostring(loadedAddons) .. ", refreshed=" .. tostring(loadedRefresh))
		else
			self:Print("loaded addon inspector unavailable.")
		end
		if self.LoadedAddonPanel and self.LoadedAddonPanel.Toggle then
			self.LoadedAddonPanel:Toggle()
		else
			self:Print("loaded addon panel unavailable.")
		end
		return
	elseif message == "events" or message == "eventlab" or message == "payloads" or message == "recorder" then
		if self.EventRecorder and self.EventRecorder.GetStats then
			local activeEvents, eventHistory, eventHistoryMax = self.EventRecorder:GetStats()
			self:Print("event lab: active=" .. tostring(activeEvents) .. ", payloads=" .. tostring(eventHistory) .. "/" .. tostring(eventHistoryMax))
		else
			self:Print("event recorder unavailable.")
		end
		if self.EventLabPanel and self.EventLabPanel.Toggle then
			self.EventLabPanel:Toggle()
		else
			self:Print("event lab panel unavailable.")
		end
		return
	elseif message == "diff" or message == "builddiff" or message == "manifest" then
		if self.BuildDiff and self.BuildDiff.GetStats then
			local diffInterface, diffApis, diffXml, diffSymbols = self.BuildDiff:GetStats()
			self:Print("build diff manifest: interface=" .. tostring(diffInterface) .. ", APIs=" .. tostring(diffApis) .. ", XML=" .. tostring(diffXml) .. ", symbols=" .. tostring(diffSymbols))
		else
			self:Print("build diff unavailable.")
		end
		if self.BuildDiffPanel and self.BuildDiffPanel.Toggle then
			self.BuildDiffPanel:Toggle()
		else
			self:Print("build diff panel unavailable.")
		end
		return
	elseif message == "stable" or message == "about" or message == "release" or message == "v1" then
		if self.StableRelease and self.StableRelease.GetStats then
			local releaseChecks, releaseVersion = self.StableRelease:GetStats()
			self:Print("release status: v" .. tostring(releaseVersion) .. ", checks=" .. tostring(releaseChecks) .. ". Live WoW validation still required.")
		else
			self:Print("stable release metadata unavailable.")
		end
		if self.StableReleasePanel and self.StableReleasePanel.Toggle then
			self.StableReleasePanel:Toggle()
		else
			self:Print("stable release panel unavailable.")
		end
		return

    elseif message == "rebuild" then
		if self.Index and self.Index.Build then
			self.Index:Build(true)
			self:Print("runtime index rebuilt.")
		end
		return
	end
	if self.UI and self.UI.Toggle then
		self.UI:Toggle()
	end
end

ApiVault.frame:RegisterEvent("ADDON_LOADED")
ApiVault.frame:SetScript("OnEvent", function(_, event, arg1)
	if event == "ADDON_LOADED" and arg1 == addonName then
		ApiVault:Init()
	end
end)

SLASH_APIVAULT1 = "/apivault"
SLASH_APIVAULT2 = "/av"
SlashCmdList.APIVAULT = function(message)
	ApiVault:Slash(message)
end
