"use strict";
/**
 * Session Cleanup Utility (Facade Pattern)
 * Issue #69: Repository delete feature
 * Issue #138: Added auto-yes-poller cleanup
 * Issue #404: Added deleteAutoYesState and stopScheduleForWorktree
 *
 * Provides a unified interface for cleaning up CLI tool sessions and pollers.
 * Uses response-poller for CLI tool sessions.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.cleanupWorktreeSessions = cleanupWorktreeSessions;
exports.cleanupMultipleWorktrees = cleanupMultipleWorktrees;
exports.killWorktreeSession = killWorktreeSession;
exports.syncWorktreesAndCleanup = syncWorktreesAndCleanup;
const response_poller_1 = require("./polling/response-poller");
const auto_yes_manager_1 = require("./polling/auto-yes-manager");
const schedule_manager_1 = require("./schedule-manager");
const tmux_capture_cache_1 = require("./tmux/tmux-capture-cache");
const types_1 = require("./cli-tools/types");
const errors_1 = require("./errors");
const logger_1 = require("../lib/logger");
const manager_1 = require("./cli-tools/manager");
const tmux_1 = require("./tmux/tmux");
const worktrees_1 = require("./git/worktrees");
const logger = (0, logger_1.createLogger)('session-cleanup');
/**
 * Clean up all CLI tool sessions and pollers for a single worktree
 *
 * This function:
 * 1. Kills all CLI tool sessions using the provided killSessionFn
 * 2. Stops response-poller for each CLI tool
 * 3. Stops auto-yes polling and deletes auto-yes state (Issue #404)
 * 4. Stops schedules for this worktree (Issue #404)
 *
 * Call order (Issue #404): stopAutoYesPolling -> deleteAutoYesState -> stopScheduleForWorktree
 *
 * Errors are collected but do not stop the cleanup process (partial success is allowed).
 *
 * @param worktreeId - ID of the worktree to clean up
 * @param killSessionFn - Function to kill a session for a specific CLI tool
 * @returns Cleanup result with killed sessions and any errors
 */
async function cleanupWorktreeSessions(worktreeId, killSessionFn) {
    const result = {
        worktreeId,
        sessionsKilled: [],
        sessionErrors: [],
        pollersStopped: [],
        pollerErrors: [],
    };
    // Issue #405: Clear all capture cache at shutdown start
    (0, tmux_capture_cache_1.clearAllCache)();
    // 1. Kill sessions and stop response-pollers for each CLI tool
    for (const cliToolId of types_1.CLI_TOOL_IDS) {
        // Kill session
        try {
            const killed = await killSessionFn(worktreeId, cliToolId);
            if (killed) {
                result.sessionsKilled.push(cliToolId);
                logger.info('session:killed', { worktreeId, cliToolId });
            }
        }
        catch (error) {
            const errorMsg = `${cliToolId}: ${(0, errors_1.getErrorMessage)(error)}`;
            result.sessionErrors.push(errorMsg);
            logger.warn('session:kill-failed', { worktreeId, cliToolId, error: error instanceof Error ? error.message : String(error) });
        }
        // Stop response-poller
        try {
            (0, response_poller_1.stopPolling)(worktreeId, cliToolId);
            result.pollersStopped.push(`response-poller:${cliToolId}`);
        }
        catch (error) {
            const errorMsg = `response-poller:${cliToolId}: ${(0, errors_1.getErrorMessage)(error)}`;
            result.pollerErrors.push(errorMsg);
            logger.warn('response-poller:stop-failed', { worktreeId, cliToolId, error: error instanceof Error ? error.message : String(error) });
        }
    }
    // 2. Stop auto-yes-poller for all agents (Issue #138, #525: byWorktree helper)
    // Order: stopAutoYesPollingByWorktree -> deleteAutoYesStateByWorktree -> stopScheduleForWorktree (Issue #404)
    try {
        (0, auto_yes_manager_1.stopAutoYesPollingByWorktree)(worktreeId);
        result.pollersStopped.push('auto-yes-poller');
    }
    catch (error) {
        const errorMsg = `auto-yes-poller: ${(0, errors_1.getErrorMessage)(error)}`;
        result.pollerErrors.push(errorMsg);
        logger.warn('auto-yes-poller:stop-failed', { worktreeId, error: error instanceof Error ? error.message : String(error) });
    }
    // 3. Delete auto-yes state for all agents (Issue #404, #525: byWorktree helper)
    try {
        (0, auto_yes_manager_1.deleteAutoYesStateByWorktree)(worktreeId);
        result.pollersStopped.push('auto-yes-state');
    }
    catch (error) {
        const errorMsg = `auto-yes-state: ${(0, errors_1.getErrorMessage)(error)}`;
        result.pollerErrors.push(errorMsg);
        logger.warn('auto-yes-state:delete-failed', { worktreeId, error: error instanceof Error ? error.message : String(error) });
    }
    // 4. Stop schedules for this worktree (Issue #404: replaces stopAllSchedules)
    try {
        (0, schedule_manager_1.stopScheduleForWorktree)(worktreeId);
        result.pollersStopped.push('schedule-manager');
    }
    catch (error) {
        const errorMsg = `schedule-manager: ${(0, errors_1.getErrorMessage)(error)}`;
        result.pollerErrors.push(errorMsg);
        logger.warn('schedule-manager:stop-failed', { worktreeId, error: error instanceof Error ? error.message : String(error) });
    }
    return result;
}
/**
 * Clean up sessions and pollers for multiple worktrees
 *
 * @param worktreeIds - Array of worktree IDs to clean up
 * @param killSessionFn - Function to kill a session for a specific CLI tool
 * @returns Aggregated cleanup results and warnings
 */
async function cleanupMultipleWorktrees(worktreeIds, killSessionFn) {
    // Issue #526 / SF-003: Parallel execution with Promise.allSettled
    const settled = await Promise.allSettled(worktreeIds.map(worktreeId => cleanupWorktreeSessions(worktreeId, killSessionFn)));
    const results = [];
    const warnings = [];
    for (let i = 0; i < settled.length; i++) {
        const outcome = settled[i];
        const worktreeId = worktreeIds[i];
        if (outcome.status === 'fulfilled') {
            const result = outcome.value;
            results.push(result);
            // Collect warnings from errors
            for (const error of result.sessionErrors) {
                warnings.push(`Session kill error (${worktreeId}): ${error}`);
            }
            for (const error of result.pollerErrors) {
                warnings.push(`Poller stop error (${worktreeId}): ${error}`);
            }
        }
        else {
            // Unexpected rejection from cleanupWorktreeSessions
            warnings.push(`Cleanup failed (${worktreeId}): ${(0, errors_1.getErrorMessage)(outcome.reason)}`);
        }
    }
    return { results, warnings };
}
/**
 * Kill a CLI tool session for a worktree
 * Issue #526: Common function extracted from repositories/route.ts
 *
 * MF-C01: getTool() throws Error if tool not found, wrapped in try-catch
 * SF-004: isRunning() correctly awaited
 *
 * @param worktreeId - Worktree ID
 * @param cliToolId - CLI tool type
 * @returns true if session was killed, false otherwise
 */
async function killWorktreeSession(worktreeId, cliToolId) {
    try {
        const manager = manager_1.CLIToolManager.getInstance();
        const tool = manager.getTool(cliToolId); // throws Error if not found
        if (!await tool.isRunning(worktreeId))
            return false; // SF-004: await
        const sessionName = tool.getSessionName(worktreeId);
        return (0, tmux_1.killSession)(sessionName);
    }
    catch {
        return false;
    }
}
/**
 * Sync worktrees to DB and clean up sessions for deleted worktrees
 * Issue #526 / MF-001: DRY helper combining sync + cleanup
 *
 * SEC-MF-001: cleanupWarnings are sanitized - detailed errors logged server-side only,
 * client-facing warnings contain only generic messages.
 *
 * @param db - Database instance
 * @param worktrees - Array of worktrees to sync
 * @returns SyncResult and sanitized cleanupWarnings
 */
async function syncWorktreesAndCleanup(db, worktrees) {
    const syncResult = (0, worktrees_1.syncWorktreesToDB)(db, worktrees);
    let cleanupWarnings = [];
    if (syncResult.deletedIds.length > 0) {
        try {
            const cleanupResult = await cleanupMultipleWorktrees(syncResult.deletedIds, killWorktreeSession);
            if (cleanupResult.warnings.length > 0) {
                // SEC-MF-001: Log detailed warnings server-side only
                logger.warn('sync:cleanup-warnings', { warnings: cleanupResult.warnings });
                // Return sanitized generic message to client
                cleanupWarnings = [`${cleanupResult.warnings.length} session cleanup warning(s) occurred`];
            }
        }
        catch (error) {
            // Cleanup failure should not break sync
            logger.error('sync:cleanup-failed', { error: (0, errors_1.getErrorMessage)(error) });
            cleanupWarnings = ['Session cleanup encountered an error'];
        }
    }
    return { syncResult, cleanupWarnings };
}
