/**
 * HealthMonitor - 健康检查核心
 * 监控 P2P、Iroh、LLM、内存等关键指标
 */
import { getMinimax } from '../constraints/index.js';
export class HealthMonitor {
    config;
    lastHeartbeatTime = Date.now();
    checkIntervalId = null;
    onStatusChange;
    constructor(config = {}) {
        this.config = config;
        this.onStatusChange = config.onStatusChange;
    }
    /**
     * 执行完整健康检查
     */
    async check() {
        const checks = {
            p2p: await this.checkP2P(),
            iroh: await this.checkIroh(),
            llm: await this.checkLLM(),
            memory: await this.checkMemory(),
            heartbeat: await this.checkHeartbeat()
        };
        // 计算整体状态
        const errors = Object.values(checks).filter(c => c.status === 'error').length;
        let status = 'healthy';
        if (errors >= 3) {
            status = 'unhealthy';
        }
        else if (errors >= 1) {
            status = 'degraded';
        }
        const healthStatus = {
            status,
            timestamp: new Date().toISOString(),
            uptime_seconds: process.uptime(),
            checks,
            recommendations: this.generateRecommendations(checks)
        };
        this.onStatusChange?.(healthStatus);
        return healthStatus;
    }
    /**
     * 检查 P2P 连接状态
     */
    async checkP2P() {
        const start = Date.now();
        try {
            // 从全局状态获取 HyperswarmCommunicator
            const comm = global.hyperswarmComm;
            if (!comm) {
                return { status: 'ok', message: 'P2P not initialized yet', latency_ms: Date.now() - start };
            }
            const connections = comm.getConnections?.() || [];
            return {
                status: 'ok',
                message: `Connected to ${connections.length} peers`,
                details: { peer_count: connections.length },
                latency_ms: Date.now() - start
            };
        }
        catch (err) {
            return { status: 'error', message: err.message, latency_ms: Date.now() - start };
        }
    }
    /**
     * 检查 Iroh 节点状态
     */
    async checkIroh() {
        const start = Date.now();
        try {
            const { irohTransport } = await import('../network/iroh-transport.js');
            if (!irohTransport.isRunning?.()) {
                return { status: 'error', message: 'Iroh not running', latency_ms: Date.now() - start };
            }
            const nodeId = irohTransport.getNodeId?.() || '';
            const peers = irohTransport.getPeers?.() || [];
            const pendingOffline = irohTransport.getPendingOfflineCount?.() || 0;
            return {
                status: 'ok',
                message: `Iroh running, ${peers.length} peers`,
                details: {
                    nodeId: nodeId.substring(0, 16) + '...',
                    peer_count: peers.length,
                    pending_offline_messages: pendingOffline
                },
                latency_ms: Date.now() - start
            };
        }
        catch (err) {
            return { status: 'error', message: err.message, latency_ms: Date.now() - start };
        }
    }
    /**
     * 检查 LLM 连接状态
     */
    async checkLLM() {
        const start = Date.now();
        try {
            const minimax = getMinimax();
            if (!minimax) {
                return { status: 'error', message: 'LLM not initialized', latency_ms: Date.now() - start };
            }
            // 执行 ping 测试
            const latency = await this.pingLLM(minimax);
            return {
                status: 'ok',
                message: 'LLM responsive',
                details: { latency_ms: latency },
                latency_ms: Date.now() - start
            };
        }
        catch (err) {
            return { status: 'error', message: err.message, latency_ms: Date.now() - start };
        }
    }
    /**
     * 检查内存使用
     */
    async checkMemory() {
        const start = Date.now();
        try {
            const usage = process.memoryUsage();
            const heapUsedPercent = (usage.heapUsed / usage.heapTotal) * 100;
            const rssPercent = (usage.rss / (1024 * 1024 * 1024)) * 100; // GB
            // 获取系统总内存 (macOS/Linux)
            let systemMemoryPercent = 0;
            try {
                if (process.platform === 'darwin' || process.platform === 'linux') {
                    const { execSync } = require('child_process');
                    if (process.platform === 'darwin') {
                        const total = execSync('sysctl -n hw.memsize').toString().trim();
                        const free = execSync('vm_stat | grep "Pages free" | awk \'{print $3}\' | tr -d "."');
                        const pageSize = execSync('sysctl -n vm.pagesize').toString().trim();
                        systemMemoryPercent = ((parseInt(free) * parseInt(pageSize)) / parseInt(total)) * 100;
                    }
                }
            }
            catch {
                // 忽略系统内存获取失败
            }
            const isHealthy = heapUsedPercent < 80;
            return {
                status: isHealthy ? 'ok' : 'error',
                message: isHealthy ? 'Memory usage normal' : 'Memory usage high',
                details: {
                    heap_used_mb: Math.round(usage.heapUsed / 1024 / 1024),
                    heap_total_mb: Math.round(usage.heapTotal / 1024 / 1024),
                    heap_used_percent: Math.round(heapUsedPercent * 10) / 10,
                    rss_mb: Math.round(usage.rss / 1024 / 1024)
                },
                latency_ms: Date.now() - start
            };
        }
        catch (err) {
            return { status: 'error', message: err.message, latency_ms: Date.now() - start };
        }
    }
    /**
     * 检查心跳活跃度
     */
    async checkHeartbeat() {
        const start = Date.now();
        const elapsed = Date.now() - this.lastHeartbeatTime;
        // 获取 SocialHeartbeat 状态
        const heartbeat = global.socialHeartbeat;
        let agentsCount = 0;
        let antColonyEnabled = false;
        if (heartbeat) {
            const agents = heartbeat.getDiscoveredAgents?.();
            agentsCount = agents?.length || 0;
            antColonyEnabled = heartbeat.isAntColonyEnabled?.() || false;
        }
        return {
            status: elapsed < 60000 ? 'ok' : 'error',
            message: elapsed < 60000
                ? `Heartbeat active ${Math.round(elapsed / 1000)}s ago`
                : 'Heartbeat inactive for > 60s',
            details: {
                last_heartbeat_ms: elapsed,
                discovered_agents: agentsCount,
                ant_colony_enabled: antColonyEnabled
            },
            latency_ms: Date.now() - start
        };
    }
    /**
     * 记录心跳活跃
     */
    recordHeartbeat() {
        this.lastHeartbeatTime = Date.now();
    }
    /**
     * 获取当前状态（不执行检查）
     */
    getQuickStatus() {
        const usage = process.memoryUsage();
        return {
            status: 'active',
            lastHeartbeat: this.lastHeartbeatTime,
            memoryUsage: Math.round((usage.heapUsed / usage.heapTotal) * 100)
        };
    }
    /**
     * 生成健康建议
     */
    generateRecommendations(checks) {
        const recommendations = [];
        if (checks.p2p.status === 'error') {
            recommendations.push('P2P 连接失败，建议检查网络');
        }
        if (checks.iroh.status === 'error') {
            recommendations.push('Iroh 节点未运行，消息可能无法发送');
        }
        if (checks.llm.status === 'error') {
            recommendations.push('LLM 连接失败，检查 API 密钥配置');
        }
        if (checks.memory.status === 'error') {
            recommendations.push('内存使用率过高，考虑重启服务');
        }
        if (checks.heartbeat.status === 'error') {
            recommendations.push('心跳长时间未活跃，检查系统是否卡死');
        }
        return recommendations;
    }
    /**
     * Ping LLM 测试响应
     */
    async pingLLM(minimax) {
        const start = Date.now();
        try {
            // 简单的 chat 测试
            if (minimax.chat) {
                await minimax.chat('ping', 'test', { maxTokens: 1 });
            }
            else if (minimax.ping) {
                await minimax.ping();
            }
            return Date.now() - start;
        }
        catch {
            // 如果 ping 失败，返回一个较大的值但不是错误
            return Date.now() - start;
        }
    }
    /**
     * 开始定期健康检查
     */
    startPeriodicCheck(intervalMs = 60000, callback) {
        if (this.checkIntervalId) {
            clearInterval(this.checkIntervalId);
        }
        const checkFn = async () => {
            const status = await this.check();
            callback?.(status);
            this.onStatusChange?.(status);
        };
        this.checkIntervalId = setInterval(checkFn, intervalMs);
        // 立即执行一次
        checkFn();
    }
    /**
     * 停止定期检查
     */
    stopPeriodicCheck() {
        if (this.checkIntervalId) {
            clearInterval(this.checkIntervalId);
            this.checkIntervalId = null;
        }
    }
}
// 全局实例
let healthMonitorInstance = null;
export function getHealthMonitor() {
    if (!healthMonitorInstance) {
        healthMonitorInstance = new HealthMonitor();
    }
    return healthMonitorInstance;
}
export function createHealthMonitor(config) {
    healthMonitorInstance = new HealthMonitor(config);
    return healthMonitorInstance;
}
