/**
 * Nexus Prime — Pressure Detector
 *
 * Detects machine pressure on macOS and Linux.
 * Used by the Governor to decide when to degrade.
 */
import { execFileSync, execSync } from 'child_process';
import { readFileSync } from 'fs';
/**
 * Detect current machine memory pressure.
 *
 * macOS: reads from `memory_pressure` or `vm_stat`
 * Linux: reads from `/proc/meminfo`
 * Falls back to 'nominal' if detection fails.
 */
export function detectMemoryPressure() {
    try {
        if (process.platform === 'darwin') {
            return detectDarwinPressure();
        }
        if (process.platform === 'linux') {
            return detectLinuxPressure();
        }
    }
    catch {
        // Detection is best-effort
    }
    return 'nominal';
}
function detectDarwinPressure() {
    try {
        // memory_pressure returns "The system has <level> memory" for current/critical/warning/normal
        const output = execSync('/usr/bin/memory_pressure -S', {
            encoding: 'utf8',
            timeout: 2000,
        });
        if (output.includes('CRITICAL') || output.includes('critical'))
            return 'critical';
        if (output.includes('WARN') || output.includes('warn'))
            return 'elevated';
        return 'nominal';
    }
    catch {
        // Fallback: check vm_stat for page-outs
        try {
            const vmstat = execSync('vm_stat', { encoding: 'utf8', timeout: 2000 });
            const pageoutsMatch = vmstat.match(/Pageouts:\s+(\d+)/);
            const pageouts = pageoutsMatch ? parseInt(pageoutsMatch[1], 10) : 0;
            if (pageouts > 100000)
                return 'elevated';
            return 'nominal';
        }
        catch {
            return 'nominal';
        }
    }
}
function detectLinuxPressure() {
    try {
        const meminfo = readFileSync('/proc/meminfo', 'utf8');
        const totalMatch = meminfo.match(/MemTotal:\s+(\d+)/);
        const availMatch = meminfo.match(/MemAvailable:\s+(\d+)/);
        if (totalMatch && availMatch) {
            const total = parseInt(totalMatch[1], 10);
            const avail = parseInt(availMatch[1], 10);
            const usedPct = (total - avail) / total;
            if (usedPct > 0.95)
                return 'critical';
            if (usedPct > 0.85)
                return 'elevated';
        }
        return 'nominal';
    }
    catch {
        return 'nominal';
    }
}
/**
 * Count active Node.js child processes (best-effort).
 */
export function estimateProcessCount() {
    try {
        const output = execFileSync('ps', ['-eo', 'comm='], {
            encoding: 'utf8',
            timeout: 2000,
            stdio: ['ignore', 'pipe', 'ignore'],
        });
        const nodeCount = output
            .split('\n')
            .map((entry) => entry.trim().toLowerCase())
            .filter((entry) => entry.endsWith('node') || entry === 'node')
            .length;
        return nodeCount || 1;
    }
    catch {
        return 1;
    }
}
