/**
 * External data sources for the TUI (policy file, Prometheus metrics, dashboard API).
 */
import { existsSync, readFileSync } from 'fs';
import { resolve, join } from 'path';
import { homedir } from 'os';
import { load } from 'js-yaml';
import { PolicyEngine } from '../policy/policy-engine.js';
import { parsePolicyConfig } from '../policy/policy-schema.js';
import { summarizeRecords } from './db-aggregate.js';
const GUARDIAN_DIR = resolve(homedir(), '.mcp-guardian');
export function resolvePolicyPath() {
    const candidates = [
        process.env.GUARDIAN_POLICY_PATH,
        process.env.MCP_GUARDIAN_POLICY,
        join(GUARDIAN_DIR, 'policy.yaml'),
        resolve(process.cwd(), 'default-policy.yaml'),
        resolve(process.cwd(), 'policy.yaml'),
    ].filter(Boolean);
    for (const p of candidates) {
        if (existsSync(p))
            return p;
    }
    return null;
}
export function computeCostTrend(records) {
    if (records.length < 4)
        return 'flat';
    const sorted = [...records].sort((a, b) => (a.timestamp || '').localeCompare(b.timestamp || ''));
    const mid = Math.floor(sorted.length / 2);
    const firstCost = summarizeRecords(sorted.slice(0, mid)).costUsd;
    const secondCost = summarizeRecords(sorted.slice(mid)).costUsd;
    if (secondCost > firstCost * 1.1)
        return 'increasing';
    if (secondCost < firstCost * 0.9)
        return 'decreasing';
    return 'flat';
}
export function parseCircuitBreakerMetrics(body) {
    const out = new Map();
    const re = /mcp_guardian_circuit_breaker_state\{server_name="([^"]+)"\}\s+(\d+(?:\.\d+)?)/g;
    let m;
    while ((m = re.exec(body)) !== null) {
        const val = parseInt(m[2], 10);
        const state = val === 1 ? 'open' : val === 2 ? 'half_open' : 'closed';
        out.set(m[1], state);
    }
    return out;
}
export async function fetchCircuitBreakerStates() {
    if (process.env.METRICS_ENABLED !== 'true')
        return new Map();
    const port = process.env.METRICS_PORT || '9090';
    const host = process.env.METRICS_HOST || '127.0.0.1';
    try {
        const res = await fetch(`http://${host}:${port}/metrics`, {
            signal: AbortSignal.timeout(2500),
        });
        if (!res.ok)
            return new Map();
        return parseCircuitBreakerMetrics(await res.text());
    }
    catch {
        return new Map();
    }
}
export function loadPolicySnapshot() {
    const empty = {
        mode: 'none',
        activeRules: 0,
        rules: [],
        autoGeneratedRules: [],
        policyPath: null,
    };
    const policyPath = resolvePolicyPath();
    if (!policyPath)
        return empty;
    try {
        const yaml = readFileSync(policyPath, 'utf-8');
        const config = parsePolicyConfig(load(yaml));
        const engine = new PolicyEngine(config);
        const autoGeneratedRules = [];
        try {
            const aiPath = join(GUARDIAN_DIR, '.ai-learning.json');
            if (existsSync(aiPath)) {
                const st = JSON.parse(readFileSync(aiPath, 'utf-8'));
                if (Array.isArray(st.autoRules))
                    autoGeneratedRules.push(...st.autoRules);
            }
        }
        catch {
            /* ignore */
        }
        return {
            mode: engine.getMode(),
            activeRules: engine.getRuleCount(),
            rules: [...engine.getRules()],
            autoGeneratedRules,
            policyPath,
        };
    }
    catch {
        return { ...empty, policyPath };
    }
}
export async function fetchDashboardMetrics(baseUrl) {
    try {
        const res = await fetch(`${baseUrl.replace(/\/$/, '')}/api/aggregate/metrics`, {
            signal: AbortSignal.timeout(3000),
        });
        if (!res.ok)
            return null;
        return (await res.json());
    }
    catch {
        return null;
    }
}
//# sourceMappingURL=tui-sources.js.map