import { randomBytes } from 'crypto';
export class SessionManager {
    agents = new Map();
    sessionToAgent = new Map();
    webClients = new Map();
    generateSessionId() {
        return randomBytes(12).toString('base64url');
    }
    // --- Agent operations ---
    registerAgent(agentId, agent) {
        this.agents.set(agentId, agent);
        this.sessionToAgent.set(agent.sessionId, agentId);
    }
    removeAgent(agentId) {
        const agent = this.agents.get(agentId);
        if (agent) {
            this.sessionToAgent.delete(agent.sessionId);
            this.agents.delete(agentId);
        }
    }
    getAgent(agentId) {
        return this.agents.get(agentId);
    }
    getAgentBySession(sessionId) {
        const agentId = this.sessionToAgent.get(sessionId);
        return agentId ? this.agents.get(agentId) : undefined;
    }
    // --- Client operations ---
    registerClient(clientId, client) {
        this.webClients.set(clientId, client);
    }
    removeClient(clientId) {
        this.webClients.delete(clientId);
    }
    getClient(clientId) {
        return this.webClients.get(clientId);
    }
    getClientsForSession(sessionId) {
        const result = [];
        for (const [, client] of this.webClients) {
            if (client.sessionId === sessionId) {
                result.push(client);
            }
        }
        return result;
    }
    // --- Heartbeat ---
    cleanupDeadConnections(notifyFn) {
        const removedAgents = [];
        const removedClients = [];
        for (const [agentId, agent] of this.agents) {
            if (!agent.isAlive) {
                console.log(`[Heartbeat] Agent ${agent.name} timed out`);
                agent.ws.terminate();
                this.sessionToAgent.delete(agent.sessionId);
                this.agents.delete(agentId);
                removedAgents.push(agentId);
                for (const [, client] of this.webClients) {
                    if (client.sessionId === agent.sessionId) {
                        notifyFn(client, { type: 'agent_disconnected' });
                    }
                }
                continue;
            }
            agent.isAlive = false;
            agent.ws.ping();
        }
        for (const [clientId, client] of this.webClients) {
            if (!client.isAlive) {
                client.ws.terminate();
                this.webClients.delete(clientId);
                removedClients.push(clientId);
                continue;
            }
            client.isAlive = false;
            client.ws.ping();
        }
        return { removedAgents, removedClients };
    }
}
// Singleton instance for backward compatibility
export const sessions = new SessionManager();
//# sourceMappingURL=session-manager.js.map