/**
 * Posture Collector
 * Phase 3: Derive dependencies, posture, risk, cause
 */
// Track last posture change timestamp
let lastPostureChange = null;
let lastPosture = null;
/**
 * Derive dependencies from app state
 */
function deriveDependencies(appState) {
    const deps = {
        config: "UNKNOWN",
        gateway: "UNKNOWN",
        database: "UNKNOWN",
        registry: "UNKNOWN",
    };
    // Config: Check if system is ready
    if (appState.systemReady) {
        deps.config = "OK";
    }
    else {
        deps.config = "ERROR";
    }
    // Gateway: Check connection
    if (appState.gatewayConnected && appState.gatewayClient) {
        deps.gateway = "OK";
    }
    else if (appState.localMode) {
        deps.gateway = "OK"; // Local mode doesn't need gateway
    }
    else if (appState.gatewayUrl) {
        deps.gateway = "WARN"; // Has URL but not connected
    }
    else {
        deps.gateway = "ERROR";
    }
    // Database: Check if persistence is available
    if (appState.gatewayConnected) {
        deps.database = "OK";
    }
    else if (appState.localMode) {
        deps.database = "WARN"; // Local mode = in-memory
    }
    else {
        deps.database = "ERROR";
    }
    // Registry: Check if agents are loaded
    if (appState.customAgents.size >= 0) {
        deps.registry = "OK";
    }
    else {
        deps.registry = "WARN";
    }
    return deps;
}
/**
 * Derive posture from dependencies
 * Deterministic rules
 */
function derivePosture(dependencies, connected) {
    // If gateway=ERROR OR database=ERROR → posture = CRITICAL
    if (dependencies.gateway === "ERROR" || dependencies.database === "ERROR") {
        return "CRITICAL";
    }
    // Else if any dependency is WARN/ERROR → posture = DEGRADED
    if (dependencies.config === "WARN" || dependencies.config === "ERROR" ||
        dependencies.gateway === "WARN" ||
        dependencies.database === "WARN" ||
        dependencies.registry === "WARN" || dependencies.registry === "ERROR") {
        return "DEGRADED";
    }
    // Else if connected=false → posture = OFFLINE (unless critical)
    if (!connected) {
        return "OFFLINE";
    }
    // Else posture = OPERATIONAL
    return "OPERATIONAL";
}
/**
 * Derive risk from posture
 */
function deriveRisk(posture) {
    if (posture === "CRITICAL")
        return "HIGH";
    if (posture === "DEGRADED")
        return "ELEVATED";
    if (posture === "OPERATIONAL")
        return "LOW";
    if (posture === "OFFLINE")
        return "ELEVATED";
    return "UNKNOWN";
}
/**
 * Derive cause from dependencies and posture
 */
function deriveCause(dependencies, posture) {
    if (posture === "OPERATIONAL") {
        return "UNKNOWN"; // Blank if operational
    }
    // Prioritize error messages
    if (dependencies.gateway === "ERROR") {
        return "Gateway connection failed";
    }
    if (dependencies.database === "ERROR") {
        return "Database unavailable";
    }
    if (dependencies.config === "ERROR") {
        return "Configuration error";
    }
    if (dependencies.registry === "ERROR") {
        return "Registry load failed";
    }
    if (dependencies.gateway === "WARN") {
        return "Gateway not connected";
    }
    if (dependencies.database === "WARN") {
        return "Database not initialized";
    }
    return "UNKNOWN";
}
/**
 * Collect posture data
 */
export async function collectPosture(appState) {
    try {
        const dependencies = deriveDependencies(appState);
        const connected = appState.gatewayConnected || appState.localMode;
        const posture = derivePosture(dependencies, connected);
        const risk = deriveRisk(posture);
        const cause = deriveCause(dependencies, posture);
        // Track last change
        if (lastPosture !== null && lastPosture !== posture) {
            lastPostureChange = Date.now();
        }
        lastPosture = posture;
        const data = {
            posture,
            risk,
            connected: connected ? true : false,
            target: appState.gatewayUrl?.replace(/^https?:\/\//, '').substring(0, 30) || "UNKNOWN",
            lastChange: lastPostureChange || "UNKNOWN",
            cause,
            dependencies,
        };
        // Phase 9: Determine status
        const now = Date.now();
        let status = 'LIVE';
        let reasonCode;
        let message;
        let action;
        if (dependencies.gateway === "ERROR" || dependencies.database === "ERROR") {
            status = 'UNAVAILABLE';
            reasonCode = dependencies.gateway === "ERROR" ? 'GATEWAY_ERROR' : 'DB_ERROR';
            message = dependencies.gateway === "ERROR"
                ? 'Gateway connection failed'
                : 'Database connection failed';
            action = dependencies.gateway === "ERROR"
                ? 'system gateway status'
                : 'system connect-db';
        }
        else if (!connected) {
            status = 'UNAVAILABLE';
            reasonCode = 'GATEWAY_NOT_CONNECTED';
            message = 'Not connected to gateway';
            action = 'system connect';
        }
        else if (dependencies.config === "ERROR") {
            status = 'UNAVAILABLE';
            reasonCode = 'CONFIG_ERROR';
            message = 'Configuration error';
            action = 'system config';
        }
        else {
            // Check if stale
            const age = now - (lastPostureChange || now);
            if (age > 2000) {
                status = 'STALE';
            }
            else {
                status = 'LIVE';
            }
        }
        return {
            status,
            asOf: now,
            data,
            source: 'collector_posture',
            staleAfterMs: 2000,
            reasonCode,
            message,
            action,
        };
    }
    catch (error) {
        return {
            status: 'UNAVAILABLE',
            asOf: Date.now(),
            source: 'collector_posture',
            staleAfterMs: 2000,
            reasonCode: 'COLLECTION_ERROR',
            message: error.message || 'Unknown error',
            action: 'system status',
        };
    }
}
//# sourceMappingURL=collector_posture.js.map