// SPEC-094 AC-8: Health monitoring for storage and service
import { access, constants, readFile } from 'node:fs/promises';
import { join } from 'node:path';
function aggregateStatus(checks) {
    if (checks.some((c) => c.status === 'fail')) {
        return 'unhealthy';
    }
    if (checks.some((c) => c.status === 'warn')) {
        return 'degraded';
    }
    return 'healthy';
}
export async function checkStorageHealth(projectPath) {
    const checks = [];
    // 1. disk-writable
    try {
        await access(projectPath, constants.W_OK);
        checks.push({ name: 'disk-writable', status: 'pass', message: 'Project path is writable' });
    }
    catch {
        checks.push({ name: 'disk-writable', status: 'fail', message: 'Project path is not writable' });
    }
    // 2. specs-json
    const specsPath = join(projectPath, 'specs.json');
    checks.push(await checkJsonFile(specsPath, 'specs-json'));
    // 3. decisions-json
    const decisionsPath = join(projectPath, 'decisions.json');
    checks.push(await checkJsonFile(decisionsPath, 'decisions-json'));
    // 4. data-dir-exists
    const dataDir = join(projectPath, '..');
    try {
        await access(dataDir, constants.R_OK);
        checks.push({ name: 'data-dir-exists', status: 'pass', message: 'Data directory exists' });
    }
    catch {
        checks.push({ name: 'data-dir-exists', status: 'fail', message: 'Data directory not found' });
    }
    return {
        status: aggregateStatus(checks),
        checks,
        timestamp: new Date().toISOString(),
    };
}
async function checkJsonFile(filePath, checkName) {
    try {
        await access(filePath, constants.R_OK);
    }
    catch {
        // File not existing is OK (not yet created)
        return { name: checkName, status: 'pass', message: `${checkName} not found (optional)` };
    }
    try {
        const content = await readFile(filePath, 'utf-8');
        JSON.parse(content);
        return { name: checkName, status: 'pass', message: `${checkName} is valid JSON` };
    }
    catch {
        return { name: checkName, status: 'fail', message: `${checkName} contains corrupt JSON` };
    }
}
export function checkServiceHealth() {
    const checks = [];
    // 1. node-version
    const versionMatch = /^v(\d+)/.exec(process.version);
    const major = versionMatch?.[1] ? parseInt(versionMatch[1], 10) : 0;
    checks.push({
        name: 'node-version',
        status: major >= 18 ? 'pass' : 'warn',
        message: `Node.js ${process.version}`,
        value: process.version,
    });
    // 2. memory-usage
    const heapUsed = process.memoryUsage().heapUsed;
    const heapMB = Math.round(heapUsed / 1024 / 1024);
    checks.push({
        name: 'memory-usage',
        status: heapMB > 500 ? 'warn' : 'pass',
        message: `Heap usage: ${heapMB}MB`,
        value: heapMB,
    });
    // 3. uptime
    const uptimeSeconds = Math.round(process.uptime());
    checks.push({
        name: 'uptime',
        status: 'pass',
        message: `Process uptime: ${uptimeSeconds}s`,
        value: uptimeSeconds,
    });
    return {
        status: aggregateStatus(checks),
        checks,
        timestamp: new Date().toISOString(),
    };
}
//# sourceMappingURL=health-monitor.js.map