/**
 * Live data providers for dashboard WebSocket push — reads real DB + AI state (no synthetic data).
 */
import { existsSync, readFileSync } from 'fs';
import { getAllActiveServerNames, loadAllCallRecords, summarizeRecords, } from './db-aggregate.js';
import { resolveAiPendingSuggestionsPath, resolveAiBaselinesPath } from '../ai/ai-paths.js';
import { getSemanticAuditStats } from '../ai/async-semantic-audit.js';
import { getAiEngine } from '../ai/suggestion-engine.js';
import { Logger } from './logger.js';
const liveCache = {
    auditEvents: [],
    metrics: null,
    instances: [],
    flagged: 0,
    lastRefresh: null,
};
let refreshTimer = null;
let boundDb = null;
export function loadPendingSuggestionsFromDisk() {
    try {
        const path = resolveAiPendingSuggestionsPath();
        if (!existsSync(path))
            return [];
        const raw = JSON.parse(readFileSync(path, 'utf-8'));
        return Array.isArray(raw.suggestions) ? raw.suggestions : [];
    }
    catch {
        return [];
    }
}
export async function refreshDashboardLiveCache(db, tenantId) {
    if (!db) {
        liveCache.auditEvents = [];
        liveCache.metrics = null;
        liveCache.instances = [];
        liveCache.flagged = getSemanticAuditStats().flagged;
        liveCache.lastRefresh = new Date().toISOString();
        return;
    }
    try {
        const srvs = await getAllActiveServerNames(db, tenantId);
        const records = await loadAllCallRecords(db, srvs, tenantId);
        const sum = summarizeRecords(records);
        const sorted = [...records].sort((a, b) => (b.timestamp || '').localeCompare(a.timestamp || ''));
        const semantic = getSemanticAuditStats();
        liveCache.auditEvents = sorted.slice(0, 50).map((r) => ({
            timestamp: r.timestamp,
            server_name: r.serverName,
            tool_name: r.toolName,
            action: r.blocked ? 'block' : 'pass',
            rule: r.blockRule ?? null,
            reason: r.blockReason ?? null,
            tenant_id: r.tenantId ?? null,
            request_tokens: r.requestTokens,
            response_tokens: r.responseTokens,
            total_tokens: r.totalTokens,
            duration_ms: r.durationMs,
            cost_usd: r.costUsd ?? null,
            model: r.model ?? null,
        }));
        liveCache.flagged = semantic.flagged;
        liveCache.metrics = {
            totalInstances: 1,
            activeInstances: 1,
            totalRequests: sum.total,
            blockedRequests: sum.blocked,
            passedRequests: sum.passed,
            totalCost: sum.costUsd,
            avgLatencyMs: sum.total > 0 ? Math.round(sum.totalLatency / sum.total) : 0,
            passRate: sum.total > 0 ? Math.round((sum.passed / sum.total) * 100) : 100,
            semanticAudit: semantic,
            lastUpdated: new Date().toISOString(),
        };
        const avgLatency = sum.total > 0 ? Math.round(sum.totalLatency / sum.total) : 0;
        liveCache.instances = [{
                instanceId: process.env.GUARDIAN_INSTANCE_ID || `guardian-${process.pid}`,
                instanceName: process.env.HOSTNAME || 'localhost',
                status: 'active',
                hostname: process.env.HOSTNAME || 'unknown',
                totalRequests: sum.total,
                blockedRequests: sum.blocked,
                totalCostUsd: sum.costUsd,
                avgLatencyMs: avgLatency,
            }];
        liveCache.lastRefresh = new Date().toISOString();
    }
    catch (err) {
        Logger.debug(`[dashboard] Live cache refresh failed: ${err instanceof Error ? err.message : String(err)}`);
    }
}
export function getDashboardLiveCache() {
    return liveCache;
}
/** Wire WsBroadcaster to real history DB + AI files; starts periodic cache refresh. */
export function wireDashboardWsProviders(ws, db) {
    boundDb = db;
    const intervalMs = parseInt(process.env.GUARDIAN_WS_PUSH_INTERVAL_MS || '5000', 10);
    if (refreshTimer) {
        clearInterval(refreshTimer);
        refreshTimer = null;
    }
    void refreshDashboardLiveCache(db);
    ws.setDataProviders({
        suggestions: () => loadPendingSuggestionsFromDisk(),
        baselines: () => {
            try {
                const path = resolveAiBaselinesPath();
                if (!existsSync(path))
                    return [];
                const raw = JSON.parse(readFileSync(path, 'utf-8'));
                return Array.isArray(raw.baselines) ? raw.baselines : Array.isArray(raw) ? raw : [];
            }
            catch {
                return [];
            }
        },
        aiReport: () => {
            const engine = getAiEngine();
            return engine ? engine.getSelfImprovement().getState() : null;
        },
        aiState: () => {
            const engine = getAiEngine();
            return engine ? engine.getSelfImprovement().getState() : null;
        },
        threats: () => [],
        metrics: () => liveCache.metrics,
        auditTrail: () => liveCache.auditEvents,
        logs: () => [],
        instances: () => liveCache.instances,
    });
    refreshTimer = setInterval(() => {
        void refreshDashboardLiveCache(boundDb);
    }, intervalMs);
    Logger.info('[dashboard] WS live data providers wired (DB + AI pending suggestions)');
}
export function stopDashboardWsProviders() {
    if (refreshTimer) {
        clearInterval(refreshTimer);
        refreshTimer = null;
    }
    boundDb = null;
}
//# sourceMappingURL=dashboard-ws-providers.js.map