/**
 * Watchdog - 看门狗机制
 * 检测进程卡死、无响应等情况
 */
export class Watchdog {
    config;
    state;
    checkIntervalId = null;
    restartStrategies = new Map();
    restartCount = 0;
    callbacks;
    constructor(config = {}, callbacks = {}) {
        this.config = {
            silentThresholdMs: config.silentThresholdMs || 300000, // 5 分钟无日志
            maxConsecutiveFailures: config.maxConsecutiveFailures || 3,
            checkIntervalMs: config.checkIntervalMs || 30000 // 30 秒检查一次
        };
        this.state = {
            lastActivityTime: Date.now(),
            consecutiveFailures: 0,
            isTriggered: false
        };
        this.callbacks = callbacks;
    }
    /**
     * 注册重启策略
     */
    registerRestartStrategy(level, action) {
        this.restartStrategies.set(level, action);
    }
    /**
     * 记录活动（调用后更新 lastActivityTime）
     */
    recordActivity(component) {
        this.state.lastActivityTime = Date.now();
        if (component) {
            this.callbacks.onLog?.(`[Watchdog] Activity from ${component}`);
        }
    }
    /**
     * 记录日志（同时触发活动检测）
     */
    log(message) {
        this.recordActivity();
        console.log(`[Watchdog] ${message}`);
        this.callbacks.onLog?.(message);
    }
    /**
     * 开始看门狗监控
     */
    start() {
        if (this.checkIntervalId)
            return;
        console.log(`[Watchdog] Started - silent threshold: ${this.config.silentThresholdMs}ms, check interval: ${this.config.checkIntervalMs}ms`);
        this.checkIntervalId = setInterval(() => {
            this.check();
        }, this.config.checkIntervalMs);
    }
    /**
     * 停止看门狗
     */
    stop() {
        if (this.checkIntervalId) {
            clearInterval(this.checkIntervalId);
            this.checkIntervalId = null;
        }
        console.log('[Watchdog] Stopped');
    }
    /**
     * 报告健康检查结果
     */
    reportHealthCheck(success, details) {
        if (success) {
            this.state.consecutiveFailures = 0;
            this.recordActivity('health_check');
        }
        else {
            this.state.consecutiveFailures++;
            console.log(`[Watchdog] Health check failed (${this.state.consecutiveFailures}/${this.config.maxConsecutiveFailures}): ${details || 'unknown'}`);
            this.callbacks.onHealthCheckFailed?.(this.state.consecutiveFailures);
            if (this.state.consecutiveFailures >= this.config.maxConsecutiveFailures) {
                this.triggerRestart(1, `Health check failed ${this.state.consecutiveFailures} times`);
            }
        }
    }
    /**
     * 获取当前状态
     */
    getState() {
        return {
            ...this.state,
            uptime_ms: Date.now() - this.state.lastActivityTime,
            restartCount: this.restartCount
        };
    }
    /**
     * 执行检查
     */
    check() {
        const now = Date.now();
        const silentTime = now - this.state.lastActivityTime;
        // 检查是否沉默太久
        if (silentTime > this.config.silentThresholdMs) {
            console.warn(`[Watchdog] No activity for ${Math.round(silentTime / 1000)}s`);
            this.triggerRestart(1, `No activity for ${Math.round(silentTime / 1000)}s`);
            return;
        }
        // 检查内存使用: 用绝对阈值, 不看 heapUsed/heapTotal 比例 (V8 内部比例不可靠, 经常 80-95% 误报)
        const usage = process.memoryUsage();
        const heapUsedMB = usage.heapUsed / 1024 / 1024;
        const rssMB = usage.rss / 1024 / 1024;
        // 1.2GB heap 或 1.5GB RSS 才是真危险
        if (heapUsedMB > 1224 || rssMB > 1536) {
            console.warn(`[Watchdog] Memory usage critical: heapUsed=${heapUsedMB.toFixed(0)}MB, rss=${rssMB.toFixed(0)}MB`);
            this.triggerRestart(1, `Memory usage heap=${heapUsedMB.toFixed(0)}MB rss=${rssMB.toFixed(0)}MB`);
        }
    }
    /**
     * 触发重启
     */
    triggerRestart(level, reason) {
        if (this.state.isTriggered) {
            console.log(`[Watchdog] Already triggered, ignoring restart request: ${reason}`);
            return;
        }
        this.state.isTriggered = true;
        this.state.triggerReason = reason;
        this.restartCount++;
        console.error(`[Watchdog] 🔴 TRIGGERED: ${reason} (restart #${this.restartCount})`);
        const strategy = this.restartStrategies.get(level);
        if (strategy) {
            try {
                this.callbacks.onRestart?.(level, reason);
                const result = strategy();
                if (result instanceof Promise) {
                    result.catch(err => {
                        console.error('[Watchdog] Restart action failed:', err);
                    });
                }
            }
            catch (err) {
                console.error('[Watchdog] Failed to execute restart strategy:', err);
            }
        }
        else {
            console.warn(`[Watchdog] No restart strategy registered for level ${level}`);
            this.callbacks.onRestart?.(level, reason);
        }
    }
    /**
     * 重置触发状态（允许再次触发）
     */
    reset() {
        this.state.isTriggered = false;
        this.state.triggerReason = undefined;
        this.state.lastActivityTime = Date.now();
    }
}
// 全局实例
let watchdogInstance = null;
export function getWatchdog() {
    if (!watchdogInstance) {
        watchdogInstance = new Watchdog();
    }
    return watchdogInstance;
}
export function createWatchdog(config, callbacks) {
    watchdogInstance = new Watchdog(config, callbacks);
    return watchdogInstance;
}
