"use strict";
/**
 * tmux session management
 * Provides functions to manage tmux sessions for Claude CLI integration
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.isTmuxAvailable = isTmuxAvailable;
exports.hasSession = hasSession;
exports.listSessions = listSessions;
exports.createSession = createSession;
exports.sendKeys = sendKeys;
exports.capturePane = capturePane;
exports.killSession = killSession;
exports.ensureSession = ensureSession;
exports.sendSpecialKey = sendSpecialKey;
const child_process_1 = require("child_process");
const util_1 = require("util");
const execAsync = (0, util_1.promisify)(child_process_1.exec);
/**
 * Default timeout for tmux commands (5 seconds)
 */
const DEFAULT_TIMEOUT = 5000;
/**
 * Check if tmux is installed and available
 */
async function isTmuxAvailable() {
    try {
        await execAsync('tmux -V', { timeout: DEFAULT_TIMEOUT });
        return true;
    }
    catch {
        return false;
    }
}
/**
 * Check if a tmux session exists
 *
 * @param sessionName - Name of the tmux session
 * @returns True if session exists, false otherwise
 *
 * @example
 * ```typescript
 * const exists = await hasSession('my-session');
 * if (exists) {
 *   console.log('Session is running');
 * }
 * ```
 */
async function hasSession(sessionName) {
    try {
        await execAsync(`tmux has-session -t "${sessionName}"`, { timeout: DEFAULT_TIMEOUT });
        return true;
    }
    catch {
        // tmux has-session returns non-zero exit code if session doesn't exist
        return false;
    }
}
/**
 * List all tmux sessions
 *
 * @returns Array of tmux session information
 *
 * @example
 * ```typescript
 * const sessions = await listSessions();
 * sessions.forEach(s => console.log(`${s.name}: ${s.windows} windows`));
 * ```
 */
async function listSessions() {
    try {
        const { stdout } = await execAsync('tmux list-sessions -F "#{session_name}|#{session_windows}|#{session_attached}"', { timeout: DEFAULT_TIMEOUT });
        if (!stdout || stdout.trim() === '') {
            return [];
        }
        return stdout
            .trim()
            .split('\n')
            .map(line => {
            const [name, windows, attached] = line.split('|');
            return {
                name,
                windows: parseInt(windows, 10) || 0,
                attached: attached === '1',
            };
        });
    }
    catch {
        // No sessions exist or tmux not running
        return [];
    }
}
/**
 * Create a new tmux session
 *
 * @param sessionNameOrOptions - Session name or options object
 * @param cwd - Working directory (when using legacy signature)
 *
 * @throws {Error} If session creation fails
 *
 * @example
 * ```typescript
 * // Legacy usage
 * await createSession('my-session', '/path/to/project');
 *
 * // New usage with options
 * await createSession({
 *   sessionName: 'my-session',
 *   workingDirectory: '/path/to/project',
 *   historyLimit: 50000,
 * });
 * ```
 */
async function createSession(sessionNameOrOptions, cwd) {
    let sessionName;
    let workingDirectory;
    let historyLimit;
    if (typeof sessionNameOrOptions === 'string') {
        // Legacy signature
        sessionName = sessionNameOrOptions;
        workingDirectory = cwd;
        historyLimit = 50000;
    }
    else {
        // New signature with options
        sessionName = sessionNameOrOptions.sessionName;
        workingDirectory = sessionNameOrOptions.workingDirectory;
        historyLimit = sessionNameOrOptions.historyLimit || 50000;
    }
    try {
        // Create session
        await execAsync(`tmux new-session -d -s "${sessionName}" -c "${workingDirectory}"`, { timeout: DEFAULT_TIMEOUT });
        // Set history limit
        await execAsync(`tmux set-option -t "${sessionName}" history-limit ${historyLimit}`, { timeout: DEFAULT_TIMEOUT });
    }
    catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to create tmux session: ${errorMessage}`);
    }
}
/**
 * Send keys to a tmux session
 *
 * @param sessionName - Target session name
 * @param keys - Keys to send (command text)
 * @param sendEnter - Whether to send Enter key after the command (default: true)
 *
 * @throws {Error} If session doesn't exist or command fails
 *
 * @example
 * ```typescript
 * await sendKeys('my-session', 'echo hello');
 * await sendKeys('my-session', 'ls -la', true);
 * await sendKeys('my-session', 'incomplete command', false);
 * ```
 */
async function sendKeys(sessionName, keys, sendEnter = true) {
    // Escape single quotes in the keys
    const escapedKeys = keys.replace(/'/g, "'\\''");
    const command = sendEnter
        ? `tmux send-keys -t "${sessionName}" '${escapedKeys}' C-m`
        : `tmux send-keys -t "${sessionName}" '${escapedKeys}'`;
    try {
        await execAsync(command, { timeout: DEFAULT_TIMEOUT });
    }
    catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to send keys to tmux session: ${errorMessage}`);
    }
}
/**
 * Capture pane output from a tmux session
 *
 * @param sessionName - Target session name
 * @param linesOrOptions - Number of lines or options object
 * @returns Captured output as string
 *
 * @example
 * ```typescript
 * // Legacy usage
 * const output = await capturePane('my-session');
 * const recent = await capturePane('my-session', 100);
 *
 * // New usage with options
 * const full = await capturePane('my-session', {
 *   startLine: -10000,
 *   endLine: -1,
 * });
 * ```
 */
async function capturePane(sessionName, linesOrOptions) {
    let startLine;
    let endLine;
    if (typeof linesOrOptions === 'number') {
        // Legacy signature
        startLine = -linesOrOptions;
        endLine = '-';
    }
    else if (linesOrOptions) {
        // New signature with options
        startLine = linesOrOptions.startLine ?? -10000;
        endLine = linesOrOptions.endLine ?? '-';
    }
    else {
        // Default
        startLine = -1000;
        endLine = '-';
    }
    try {
        const { stdout } = await execAsync(`tmux capture-pane -t "${sessionName}" -p -e -S ${startLine} -E ${endLine}`, {
            timeout: DEFAULT_TIMEOUT,
            maxBuffer: 10 * 1024 * 1024 // 10MB buffer for large Claude outputs
        });
        return stdout;
    }
    catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to capture pane: ${errorMessage}`);
    }
}
/**
 * Kill a tmux session
 *
 * @param sessionName - Session name to kill
 * @returns True if session was killed, false if session didn't exist
 *
 * @example
 * ```typescript
 * const killed = await killSession('my-session');
 * if (killed) {
 *   console.log('Session terminated');
 * }
 * ```
 */
async function killSession(sessionName) {
    try {
        await execAsync(`tmux kill-session -t "${sessionName}"`, {
            timeout: DEFAULT_TIMEOUT,
        });
        return true;
    }
    catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        // Session doesn't exist or already killed
        if (errorMessage?.includes('no server running') ||
            errorMessage?.includes("can't find session")) {
            return false;
        }
        // Re-throw unexpected errors
        throw new Error(`Failed to kill tmux session: ${errorMessage}`);
    }
}
/**
 * Ensure a tmux session exists, creating it if necessary
 *
 * @param sessionName - Session name
 * @param cwd - Working directory for the session
 *
 * @example
 * ```typescript
 * // Will create session if it doesn't exist
 * await ensureSession('my-session', '/path/to/project');
 *
 * // Safe to call multiple times
 * await ensureSession('my-session', '/path/to/project');
 * ```
 */
async function ensureSession(sessionName, cwd) {
    const exists = await hasSession(sessionName);
    if (!exists) {
        await createSession(sessionName, cwd);
    }
}
/**
 * Send a special key to a tmux session
 *
 * @param sessionName - Target session name
 * @param key - Special key to send (Escape, C-c, C-d)
 *
 * @throws {Error} If session doesn't exist or command fails
 *
 * @example
 * ```typescript
 * // Send Escape key to interrupt CLI processing
 * await sendSpecialKey('my-session', 'Escape');
 *
 * // Send Ctrl+C for SIGINT
 * await sendSpecialKey('my-session', 'C-c');
 * ```
 */
async function sendSpecialKey(sessionName, key) {
    try {
        await execAsync(`tmux send-keys -t "${sessionName}" ${key}`, { timeout: DEFAULT_TIMEOUT });
    }
    catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        throw new Error(`Failed to send special key: ${errorMessage}`);
    }
}
