"use strict";
/**
 * Auth Session Manager
 *
 * Tracks active OAuth sessions and provides cancellation capability.
 * Used to properly terminate in-progress OAuth flows from UI.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.cancelAllSessionsForProvider = exports.hasActiveSession = exports.getActiveSessionForProvider = exports.getActiveSession = exports.cancelAuthSession = exports.unregisterAuthSession = exports.attachProcessToSession = exports.registerAuthSession = exports.authSessionEvents = void 0;
const events_1 = require("events");
// H8: TTL for stale session cleanup (10 minutes - generous for OAuth flows)
const SESSION_TTL_MS = 10 * 60 * 1000;
exports.authSessionEvents = new events_1.EventEmitter();
const activeSessions = new Map();
// H8: Periodic cleanup of stale sessions (prevents memory leak from orphaned sessions)
let cleanupInterval = null;
function startCleanupInterval() {
    if (cleanupInterval)
        return;
    cleanupInterval = setInterval(() => {
        const now = Date.now();
        for (const [sessionId, session] of activeSessions.entries()) {
            if (now - session.startedAt > SESSION_TTL_MS) {
                // Stale session - kill process if still running, then remove
                if (session.process && !session.process.killed) {
                    session.process.kill('SIGTERM');
                }
                activeSessions.delete(sessionId);
                exports.authSessionEvents.emit('session:expired', sessionId);
            }
        }
        stopCleanupIfEmpty();
    }, 60000); // Check every minute
}
/** Clear the cleanup interval when no sessions remain. */
function stopCleanupIfEmpty() {
    if (activeSessions.size === 0 && cleanupInterval) {
        clearInterval(cleanupInterval);
        cleanupInterval = null;
    }
}
/**
 * Register an active OAuth session
 */
function registerAuthSession(sessionId, provider, process) {
    activeSessions.set(sessionId, {
        sessionId,
        provider,
        startedAt: Date.now(),
        process,
    });
    // H8: Start TTL cleanup when first session registered
    startCleanupInterval();
    exports.authSessionEvents.emit('session:started', sessionId, provider);
}
exports.registerAuthSession = registerAuthSession;
/**
 * Update session with process reference (if registered before spawn)
 */
function attachProcessToSession(sessionId, process) {
    const session = activeSessions.get(sessionId);
    if (session) {
        session.process = process;
    }
}
exports.attachProcessToSession = attachProcessToSession;
/**
 * Unregister an auth session (on completion or cancellation)
 */
function unregisterAuthSession(sessionId) {
    activeSessions.delete(sessionId);
    exports.authSessionEvents.emit('session:ended', sessionId);
    stopCleanupIfEmpty();
}
exports.unregisterAuthSession = unregisterAuthSession;
/**
 * Cancel an active OAuth session
 * Returns true if session was found and killed
 */
function cancelAuthSession(sessionId) {
    const session = activeSessions.get(sessionId);
    if (!session) {
        return false;
    }
    // Kill the process if attached
    if (session.process && !session.process.killed) {
        session.process.kill('SIGTERM');
    }
    activeSessions.delete(sessionId);
    exports.authSessionEvents.emit('session:cancelled', sessionId);
    stopCleanupIfEmpty();
    return true;
}
exports.cancelAuthSession = cancelAuthSession;
/**
 * Get active session by session ID
 */
function getActiveSession(sessionId) {
    return activeSessions.get(sessionId) || null;
}
exports.getActiveSession = getActiveSession;
/**
 * Get active session for a provider (most recent by startedAt)
 */
function getActiveSessionForProvider(provider) {
    let latest = null;
    for (const session of activeSessions.values()) {
        if (session.provider === provider && (!latest || session.startedAt > latest.startedAt)) {
            latest = session;
        }
    }
    return latest;
}
exports.getActiveSessionForProvider = getActiveSessionForProvider;
/**
 * Check if there's an active session for provider
 */
function hasActiveSession(provider) {
    return getActiveSessionForProvider(provider) !== null;
}
exports.hasActiveSession = hasActiveSession;
/**
 * Cancel all sessions for a provider
 */
function cancelAllSessionsForProvider(provider) {
    let count = 0;
    for (const [sessionId, session] of activeSessions.entries()) {
        if (session.provider === provider) {
            if (session.process && !session.process.killed) {
                session.process.kill('SIGTERM');
            }
            activeSessions.delete(sessionId);
            exports.authSessionEvents.emit('session:cancelled', sessionId);
            count++;
        }
    }
    stopCleanupIfEmpty();
    return count;
}
exports.cancelAllSessionsForProvider = cancelAllSessionsForProvider;
//# sourceMappingURL=auth-session-manager.js.map