/**
 * Engine Session Manager
 *
 * In-memory session store for the headless API engine.
 * Each session gets a preset-scoped toolMap and tracks call history.
 */
const sessions = new Map();
const MAX_SESSIONS = 100;
const IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
function genSessionId() {
    return `eng_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
}
function genCallId() {
    return `tcl_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
}
/**
 * Build a scoped toolMap for a preset.
 * Falls back to full toolMap if preset is unknown.
 */
export function createSession(preset, presets, toolsetMap, fallbackToolMap) {
    cleanExpired();
    if (sessions.size >= MAX_SESSIONS) {
        // Evict oldest idle session
        let oldest = null;
        for (const s of sessions.values()) {
            if (!oldest || s.lastActivity < oldest.lastActivity)
                oldest = s;
        }
        if (oldest)
            sessions.delete(oldest.id);
    }
    const toolMap = new Map();
    const domains = presets[preset] ?? presets["full"] ?? Object.keys(toolsetMap);
    for (const domain of domains) {
        const tools = toolsetMap[domain];
        if (tools) {
            for (const tool of tools) {
                toolMap.set(tool.name, tool);
            }
        }
    }
    // Always include meta/discovery tools from the fallback
    for (const [name, tool] of fallbackToolMap) {
        if (name.startsWith("find") || name === "getMethodology" || name === "check_mcp_setup"
            || name === "discover_tools" || name === "get_tool_quick_ref" || name === "get_workflow_chain") {
            toolMap.set(name, tool);
        }
    }
    const session = {
        id: genSessionId(),
        createdAt: Date.now(),
        lastActivity: Date.now(),
        preset,
        toolMap,
        callHistory: [],
        disclosureEvents: [],
        status: "active",
    };
    sessions.set(session.id, session);
    return session;
}
export function getSession(id) {
    const s = sessions.get(id);
    if (s)
        s.lastActivity = Date.now();
    return s;
}
export function endSession(id) {
    const s = sessions.get(id);
    if (!s)
        return false;
    s.status = "completed";
    sessions.delete(id);
    return true;
}
export function listSessions() {
    return Array.from(sessions.values()).map((s) => ({
        id: s.id,
        preset: s.preset,
        status: s.status,
        toolCount: s.toolMap.size,
        callCount: s.callHistory.length,
        createdAt: s.createdAt,
        lastActivity: s.lastActivity,
    }));
}
export async function executeToolInSession(session, toolName, args) {
    const tool = session.toolMap.get(toolName);
    if (!tool) {
        const record = {
            id: genCallId(),
            toolName,
            args,
            result: { error: `Tool "${toolName}" not available in preset "${session.preset}"` },
            status: "error",
            durationMs: 0,
            timestamp: Date.now(),
        };
        session.callHistory.push(record);
        return record;
    }
    const start = Date.now();
    let result;
    let status = "success";
    try {
        result = await tool.handler(args);
    }
    catch (err) {
        result = { error: err.message ?? String(err) };
        status = "error";
    }
    const record = {
        id: genCallId(),
        toolName,
        args,
        result,
        status,
        durationMs: Date.now() - start,
        timestamp: Date.now(),
    };
    session.callHistory.push(record);
    session.lastActivity = Date.now();
    return record;
}
export function cleanExpired() {
    const now = Date.now();
    let cleaned = 0;
    for (const [id, s] of sessions) {
        if (now - s.lastActivity > IDLE_TIMEOUT_MS) {
            sessions.delete(id);
            cleaned++;
        }
    }
    return cleaned;
}
export function getSessionCount() {
    return sessions.size;
}
//# sourceMappingURL=session.js.map