/**
 * WebSocket Handler
 *
 * WebSocket connection management for interactive terminals.
 */
import { trackListeners } from '../index.js';
const wsClients = new Map();
function generateClientId() {
    return `ws-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
}
export function notifyClientsOfNewSession(agentId, session, events) {
    for (const [clientId, client] of wsClients) {
        if (client.ws.data.agentId === agentId) {
            client.ws.data.sessionId = session.id;
            client.ws.data.isInteractive = session.mode === 'interactive';
            if (client.cleanup) {
                client.cleanup();
            }
            const onEvent = (event) => {
                client.ws.send(JSON.stringify({ type: 'event', event }));
            };
            const onPtyData = (ptyData) => {
                client.ws.send(JSON.stringify({ type: 'pty-data', data: ptyData }));
            };
            const onError = (error) => {
                client.ws.send(JSON.stringify({ type: 'error', error: error.message }));
            };
            const onExit = (code, signal) => {
                client.ws.send(JSON.stringify({ type: 'exit', code, signal }));
                client.ws.data.sessionId = undefined;
                client.ws.data.isInteractive = undefined;
            };
            client.cleanup = trackListeners(events, {
                'event': onEvent,
                'pty-data': onPtyData,
                'error': onError,
                'exit': onExit,
            });
            client.ws.send(JSON.stringify({
                type: 'session-started',
                agentId,
                sessionId: session.id,
                isInteractive: session.mode === 'interactive',
            }));
            console.log(`[orchestrator:ws] Notified client ${clientId} of new session for agent ${agentId}`);
        }
    }
}
export function handleWSOpen(ws) {
    const clientId = generateClientId();
    ws.data = { id: clientId };
    wsClients.set(clientId, { ws });
    console.log(`[orchestrator:ws] Client connected: ${clientId}`);
}
export function handleWSMessage(ws, message, services) {
    const { sessionManager, spawnerService } = services;
    try {
        const data = JSON.parse(message.toString());
        switch (data.type) {
            case 'subscribe': {
                if (data.agentId) {
                    ws.data.agentId = data.agentId;
                    const client = wsClients.get(ws.data.id);
                    if (client?.cleanup) {
                        client.cleanup();
                        client.cleanup = undefined;
                    }
                    const activeSession = sessionManager.getActiveSession(data.agentId);
                    if (activeSession) {
                        ws.data.sessionId = activeSession.id;
                        ws.data.isInteractive = activeSession.mode === 'interactive';
                        const events = spawnerService.getEventEmitter(activeSession.id);
                        if (events) {
                            const onEvent = (event) => {
                                ws.send(JSON.stringify({ type: 'event', event }));
                            };
                            const onPtyData = (ptyData) => {
                                ws.send(JSON.stringify({ type: 'pty-data', data: ptyData }));
                            };
                            const onError = (error) => {
                                ws.send(JSON.stringify({ type: 'error', error: error.message }));
                            };
                            const onExit = (code, signal) => {
                                ws.send(JSON.stringify({ type: 'exit', code, signal }));
                            };
                            wsClients.get(ws.data.id).cleanup = trackListeners(events, {
                                'event': onEvent,
                                'pty-data': onPtyData,
                                'error': onError,
                                'exit': onExit,
                            });
                        }
                    }
                    ws.send(JSON.stringify({
                        type: 'subscribed',
                        agentId: data.agentId,
                        hasSession: !!activeSession,
                        isInteractive: activeSession?.mode === 'interactive',
                    }));
                }
                break;
            }
            case 'input': {
                if (ws.data.sessionId && data.input && !ws.data.isInteractive) {
                    spawnerService.sendInput(ws.data.sessionId, data.input).catch((err) => {
                        ws.send(JSON.stringify({ type: 'error', error: err.message }));
                    });
                }
                else if (ws.data.sessionId && data.input && ws.data.isInteractive) {
                    spawnerService.writeToPty(ws.data.sessionId, data.input).catch((err) => {
                        ws.send(JSON.stringify({ type: 'error', error: err.message }));
                    });
                    sessionManager.recordUserInput(ws.data.sessionId);
                }
                break;
            }
            case 'resize': {
                if (ws.data.sessionId && ws.data.isInteractive && data.cols && data.rows) {
                    spawnerService.resize(ws.data.sessionId, data.cols, data.rows).catch((err) => {
                        ws.send(JSON.stringify({ type: 'error', error: err.message }));
                    });
                }
                break;
            }
            case 'ping': {
                ws.send(JSON.stringify({ type: 'pong' }));
                break;
            }
        }
    }
    catch (err) {
        console.error('[orchestrator:ws] Error handling message:', err);
    }
}
export function handleWSClose(ws) {
    const client = wsClients.get(ws.data.id);
    if (client?.cleanup) {
        client.cleanup();
    }
    wsClients.delete(ws.data.id);
    console.log(`[orchestrator:ws] Client disconnected: ${ws.data.id}`);
}
//# sourceMappingURL=websocket.js.map