/**
 * 进程管理 API 路由
 *
 * 提供 Agent 进程的全局发现、生命周期管理、健康检查和孤儿回收功能
 */
import { Router } from 'express';
import { validateToken } from '../middleware/auth.js';
import { getAgentProcessManager } from '../services/agent-process-manager.js';
import { discoverAllProcessesFull } from '../services/process-detector.js';
import { createLogger } from '../utils/logger.js';
const log = createLogger('processes');
export const processesRouter = Router();
/**
 * 列出机器上所有 Agent 进程（含管理状态）
 * GET /runtime/processes
 *
 * 返回：
 * - managed: 被 bridge 管理的进程
 * - orphan: 在运行但脱离 bridge 控制的进程
 * - unknown: 注册表中记录但进程已退出
 */
processesRouter.get('/processes', validateToken, async (_req, res) => {
    try {
        const manager = getAgentProcessManager();
        const registryRecords = manager.getAllManagedProcesses();
        // 构建 registry 导出供发现使用
        const registryExport = registryRecords
            .filter(r => r.pid > 0)
            .map(r => ({ agentId: r.agentId, pid: r.pid }));
        // 全局发现：扫描全机进程 + 对比注册表
        const discovered = discoverAllProcessesFull(registryExport);
        // 补充 sessionId 信息
        const enriched = discovered.map(d => {
            const record = registryRecords.find(r => r.pid === d.pid || r.agentId === d.agentId);
            return {
                ...d,
                sessionId: record?.sessionId,
                state: record?.state,
            };
        });
        res.json({
            ok: true,
            processes: enriched,
            stats: manager.getStats(),
        });
    }
    catch (error) {
        const err = error;
        log.error('[processes/list] Error:', err);
        res.status(500).json({ error: err.message });
    }
});
/**
 * 触发全机进程发现扫描
 * POST /runtime/processes/discover
 *
 * 主动扫描机器上所有 Agent 进程，对比注册表，
 * 标记 orphan/unknown 状态
 */
processesRouter.post('/processes/discover', validateToken, async (_req, res) => {
    try {
        const manager = getAgentProcessManager();
        const discovered = await manager.discoverAllProcesses();
        res.json({
            ok: true,
            discovered,
            managedCount: discovered.filter(d => d.managementStatus === 'managed').length,
            orphanCount: discovered.filter(d => d.managementStatus === 'orphan').length,
            unknownCount: discovered.filter(d => d.managementStatus === 'unknown').length,
        });
    }
    catch (error) {
        const err = error;
        log.error('[processes/discover] Error:', err);
        res.status(500).json({ error: err.message });
    }
});
/**
 * 获取单个进程详情
 * GET /runtime/processes/:agentId
 */
processesRouter.get('/processes/:agentId', validateToken, async (req, res) => {
    const agentIdParam = req.params.agentId;
    const agentId = Array.isArray(agentIdParam) ? agentIdParam[0] : agentIdParam;
    if (!agentId) {
        res.status(400).json({ error: 'agentId is required' });
        return;
    }
    try {
        const manager = getAgentProcessManager();
        const process = manager.getProcess(agentId);
        if (!process) {
            res.status(404).json({ error: 'Process not found', agentId });
            return;
        }
        res.json({
            ok: true,
            process,
        });
    }
    catch (error) {
        const err = error;
        log.error('[processes/get] Error:', err);
        res.status(500).json({ error: err.message });
    }
});
/**
 * 回收脱离控制的进程
 * POST /runtime/processes/:agentId/reclaim
 *
 * 尝试将脱离 bridge 管理的进程重新纳入控制
 */
processesRouter.post('/processes/:agentId/reclaim', validateToken, async (req, res) => {
    const agentIdParam = req.params.agentId;
    const agentId = Array.isArray(agentIdParam) ? agentIdParam[0] : agentIdParam;
    if (!agentId) {
        res.status(400).json({ error: 'agentId is required' });
        return;
    }
    try {
        const manager = getAgentProcessManager();
        const result = await manager.reclaimOrphan(agentId);
        res.json({
            ok: result.success,
            agentId,
            pid: result.pid,
            action: result.action,
            message: result.action === 'adopted'
                ? '进程已重新纳入管理'
                : result.action === 'terminated'
                    ? '进程已被终止'
                    : '回收失败',
        });
    }
    catch (error) {
        const err = error;
        log.error('[processes/reclaim] Error:', err);
        res.status(500).json({ error: err.message });
    }
});
/**
 * 强制终止进程（升级策略）
 * POST /runtime/processes/:agentId/force-kill
 *
 * 使用 4 级升级策略强制终止进程：
 * Level 1: SIGTERM → 等待 3s
 * Level 2: taskkill /F (Win) 或 kill -9 (Unix) → 等待 3s
 * Level 3: terminateProcessTree → 等待 5s
 * Level 4: 标记为 unstoppable
 */
processesRouter.post('/processes/:agentId/force-kill', validateToken, async (req, res) => {
    const agentIdParam = req.params.agentId;
    const agentId = Array.isArray(agentIdParam) ? agentIdParam[0] : agentIdParam;
    if (!agentId) {
        res.status(400).json({ error: 'agentId is required' });
        return;
    }
    try {
        const manager = getAgentProcessManager();
        const result = await manager.forceKill(agentId);
        res.json({
            ok: result.success,
            agentId,
            pid: result.pid,
            level: result.level,
            terminated: result.terminated,
            failed: result.failed,
            message: result.message,
        });
    }
    catch (error) {
        const err = error;
        log.error('[processes/force-kill] Error:', err);
        res.status(500).json({ error: err.message });
    }
});
/**
 * 批量扫描并回收所有孤儿进程
 * POST /runtime/processes/scan-reclaim-all
 */
processesRouter.post('/processes/scan-reclaim-all', validateToken, async (_req, res) => {
    try {
        const manager = getAgentProcessManager();
        const results = await manager.scanAndReclaimAll();
        res.json({
            ok: true,
            scanned: results.length,
            results,
        });
    }
    catch (error) {
        const err = error;
        log.error('[processes/scan-reclaim-all] Error:', err);
        res.status(500).json({ error: err.message });
    }
});
/**
 * 获取进程健康状态
 * GET /runtime/processes/:agentId/health
 */
processesRouter.get('/processes/:agentId/health', validateToken, async (req, res) => {
    const agentIdParam = req.params.agentId;
    const agentId = Array.isArray(agentIdParam) ? agentIdParam[0] : agentIdParam;
    if (!agentId) {
        res.status(400).json({ error: 'agentId is required' });
        return;
    }
    try {
        const manager = getAgentProcessManager();
        const health = await manager.healthCheck(agentId);
        res.json({
            ok: true,
            agentId,
            health,
        });
    }
    catch (error) {
        const err = error;
        log.error('[processes/health] Error:', err);
        res.status(500).json({ error: err.message });
    }
});
/**
 * 批量健康检查
 * POST /runtime/processes/health-check-all
 */
processesRouter.post('/processes/health-check-all', validateToken, async (_req, res) => {
    try {
        const manager = getAgentProcessManager();
        const results = await manager.healthCheckAll();
        const healthArray = Array.from(results.entries()).map(([_agentId, health]) => ({
            ...health,
        }));
        res.json({
            ok: true,
            checked: healthArray.length,
            health: healthArray,
        });
    }
    catch (error) {
        const err = error;
        log.error('[processes/health-check-all] Error:', err);
        res.status(500).json({ error: err.message });
    }
});
