"use strict";
// =============================================================================
// Pure Agent - Gateway Session Management
// Ported from Hermes gateway/session.py
// =============================================================================
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionStore = void 0;
exports.buildSessionKey = buildSessionKey;
const crypto = __importStar(require("crypto"));
const logger_1 = require("../logger");
// ---------------------------------------------------------------------------
// Session key builder
// ---------------------------------------------------------------------------
function buildSessionKey(source, groupSessionsPerUser = true, threadSessionsPerUser = false) {
    const platform = source.platform;
    const chatType = source.chatType;
    if (chatType === 'dm') {
        // DMs: per-user
        return `agent:dm:${platform}:${hashId(source.chatId)}`;
    }
    if (groupSessionsPerUser) {
        // Groups: per-user within group
        const threadPart = source.threadId ? `:t${hashId(source.threadId)}` : '';
        return `agent:group:${platform}:${hashId(source.chatId)}${threadPart}:u${hashId(source.userId || 'anon')}`;
    }
    if (threadSessionsPerUser && source.threadId) {
        return `agent:thread:${platform}:${hashId(source.threadId)}:u${hashId(source.userId || 'anon')}`;
    }
    // Group-wide session
    return `agent:group:${platform}:${hashId(source.chatId)}`;
}
function hashId(value) {
    return crypto.createHash('sha256').update(value).digest('hex').slice(0, 12);
}
// ---------------------------------------------------------------------------
// SessionStore
// ---------------------------------------------------------------------------
class SessionStore {
    _config;
    _sessions = new Map();
    constructor(_config) {
        this._config = _config;
    }
    getOrCreateSession(source, forceNew = false) {
        const key = buildSessionKey(source, this._config.groupSessionsPerUser, this._config.threadSessionsPerUser);
        if (!forceNew) {
            const existing = this._sessions.get(key);
            if (existing) {
                existing.updatedAt = new Date().toISOString();
                return existing;
            }
        }
        const sessionId = `sess_${hashId(key + Date.now().toString())}`;
        const entry = {
            sessionKey: key,
            sessionId,
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
            origin: source,
            displayName: source.userName || source.chatName || source.chatId,
            platform: source.platform,
            chatType: source.chatType,
            inputTokens: 0,
            outputTokens: 0,
            totalTokens: 0,
            suspended: false,
            resumePending: false,
        };
        this._sessions.set(key, entry);
        (0, logger_1.getLogger)().info(`Created session ${sessionId} for ${source.platform}:${source.chatId}`);
        return entry;
    }
    getSession(sessionKey) {
        return this._sessions.get(sessionKey);
    }
    updateSession(sessionKey, updates) {
        const entry = this._sessions.get(sessionKey);
        if (entry) {
            Object.assign(entry, updates, { updatedAt: new Date().toISOString() });
        }
    }
    resetSession(sessionKey) {
        const entry = this._sessions.get(sessionKey);
        if (!entry)
            return undefined;
        const newSessionId = `sess_${hashId(sessionKey + Date.now().toString())}`;
        entry.sessionId = newSessionId;
        entry.inputTokens = 0;
        entry.outputTokens = 0;
        entry.totalTokens = 0;
        entry.updatedAt = new Date().toISOString();
        (0, logger_1.getLogger)().info(`Reset session ${sessionKey} -> new session ${newSessionId}`);
        return entry;
    }
    listSessions() {
        return Array.from(this._sessions.values())
            .sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
    }
    pruneOld(maxAgeDays) {
        const cutoff = new Date(Date.now() - maxAgeDays * 86400000);
        let pruned = 0;
        for (const [key, entry] of this._sessions) {
            if (new Date(entry.updatedAt) < cutoff) {
                this._sessions.delete(key);
                pruned++;
            }
        }
        return pruned;
    }
}
exports.SessionStore = SessionStore;
//# sourceMappingURL=session.js.map