/**
 * Agent Cleanup Tool
 *
 * Clean up stale/dead agents and tasks.
 */
import { log } from '../utils/logger.js';
import { AgentRegistryManager } from '../core/agent-registry.js';
import { cleanupStaleAgents, checkAgentHealth } from '../utils/agent-utils.js';
import { existsSync, readdirSync, rmSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
export const agentCleanupTool = {
    name: 'agent_cleanup',
    label: 'Clean Up Agents',
    description: 'Clean up stale/dead agents and tasks',
    parameters: {
        type: 'object',
        properties: {
            force: {
                type: 'boolean',
                description: 'Force cleanup without confirmation',
                default: false,
            },
            cleanup_threshold_minutes: {
                type: 'number',
                description: 'Cleanup threshold in minutes',
                default: 5,
            },
            purge_workspaces: {
                type: 'boolean',
                description: 'Also delete workspace directories for dead agents (prevents phantom rehydration)',
                default: false,
            },
        },
        required: [],
    },
    async execute(toolCallId, params, signal, onUpdate, context) {
        const force = params.force || false;
        const cleanupThresholdMinutes = params.cleanup_threshold_minutes || 5;
        try {
            const registry = new AgentRegistryManager();
            const agents = registry.getAgents();
            if (agents.length === 0) {
                return {
                    content: [{ type: 'text', text: 'No agents in registry.' }],
                };
            }
            let output = `🧹 **Agent Cleanup**\n\n`;
            output += `Found ${agents.length} agents in registry.\n\n`;
            // Check agent health
            const healthChecks = [];
            for (const agent of agents) {
                if (agent.type === 'self') {
                    // Skip self agents
                    healthChecks.push({ agent, isHealthy: true });
                    continue;
                }
                try {
                    const isHealthy = await checkAgentHealth(agent.endpoint, 3000);
                    healthChecks.push({ agent, isHealthy });
                }
                catch (error) {
                    healthChecks.push({
                        agent,
                        isHealthy: false,
                        error: error instanceof Error ? error.message : String(error)
                    });
                }
            }
            // Identify dead agents
            const deadAgents = healthChecks.filter(check => !check.isHealthy);
            const liveAgents = healthChecks.filter(check => check.isHealthy);
            output += `**Health Check Results:**\n`;
            output += `- ✅ Live agents: ${liveAgents.length}\n`;
            output += `- ❌ Dead agents: ${deadAgents.length}\n\n`;
            if (deadAgents.length > 0) {
                output += `**Dead Agents:**\n`;
                for (const check of deadAgents) {
                    output += `- ${check.agent.name} (${check.agent.id}) - ${check.error || 'Unreachable'}\n`;
                }
                output += `\n`;
            }
            const rehydratableDeadAgents = deadAgents.filter(check => check.agent.autoStart === true);
            const removableDeadAgents = deadAgents.filter(check => check.agent.autoStart !== true);
            // Clean up stale agents from registry
            const cleanedStale = cleanupStaleAgents(cleanupThresholdMinutes * 60 * 1000, registry);
            output += `**Registry Cleanup:**\n`;
            output += `- Cleaned ${cleanedStale} stale non-auto-start agents\n`;
            output += `- Preserved ${rehydratableDeadAgents.length} auto-start dead agents for rehydration\n\n`;
            // Clean up dead agents if confirmed
            let cleanedDead = 0;
            let preservedDead = rehydratableDeadAgents.length;
            if (removableDeadAgents.length > 0 && (force || removableDeadAgents.length <= 3)) {
                // Auto-clean only non-auto-start dead agents unless forced through config changes elsewhere
                for (const check of removableDeadAgents) {
                    registry.removeAgent(check.agent.id);
                    cleanedDead++;
                }
                registry.save();
                output += `**Removed ${cleanedDead} dead non-auto-start agents from registry.**\n`;
            }
            else if (removableDeadAgents.length > 0) {
                output += `**⚠️  Found ${removableDeadAgents.length} removable dead agents.**\n`;
                output += `Use \`--force true\` to remove them, or run cleanup again.\n`;
            }
            if (preservedDead > 0) {
                output += `**Preserved ${preservedDead} dead auto-start agents for rehydration.**\n`;
            }
            // Purge workspace directories for dead agents if requested
            let purgedWorkspaces = 0;
            if (params.purge_workspaces) {
                const agentsDir = join(homedir(), '.clawx', 'agents');
                const liveIds = new Set(liveAgents.map(c => c.agent.id));
                if (existsSync(agentsDir)) {
                    for (const entry of readdirSync(agentsDir)) {
                        const workspace = join(agentsDir, entry);
                        if (liveIds.has(entry))
                            continue; // keep live agent dirs
                        try {
                            rmSync(workspace, { recursive: true, force: true });
                            purgedWorkspaces++;
                        }
                        catch (e) {
                            log.warn(`Failed to purge workspace ${workspace}: ${e instanceof Error ? e.message : String(e)}`);
                        }
                    }
                }
                output += `**Purged ${purgedWorkspaces} stale workspace directories.**\n`;
            }
            // Clean up old tasks and stale running tasks tied to dead/offline agents
            const cleanedTasks = registry.cleanupOldTasks(24 * 60 * 60 * 1000, cleanupThresholdMinutes * 60 * 1000);
            if (cleanedTasks > 0) {
                registry.save();
                output += `**Cleaned ${cleanedTasks} old/stale tasks.**\n`;
            }
            output += `\n**Summary:**\n`;
            output += `- Total agents: ${agents.length}\n`;
            output += `- Live agents: ${liveAgents.length}\n`;
            output += `- Dead agents: ${deadAgents.length}\n`;
            output += `- Preserved dead auto-start agents: ${preservedDead}\n`;
            output += `- Cleaned stale: ${cleanedStale}\n`;
            output += `- Cleaned dead: ${cleanedDead}\n`;
            output += `- Cleaned old tasks: ${cleanedTasks}\n`;
            return {
                content: [{ type: 'text', text: output }],
                details: {
                    total_agents: agents.length,
                    live_agents: liveAgents.length,
                    dead_agents: deadAgents.length,
                    preserved_dead_autostart: preservedDead,
                    cleaned_stale: cleanedStale,
                    cleaned_dead: cleanedDead,
                    cleaned_tasks: cleanedTasks,
                },
            };
        }
        catch (error) {
            log.error('Agent cleanup failed:', error);
            return {
                content: [{
                        type: 'text',
                        text: `❌ Agent cleanup failed: ${error instanceof Error ? error.message : String(error)}`,
                    }],
                details: { error: error instanceof Error ? error.message : String(error) },
                isError: true,
            };
        }
    },
};
//# sourceMappingURL=agentCleanup.js.map