"use strict";
const crypto = require("node:crypto");

class SessionManager {
  constructor({ absoluteTtl = 12 * 3600, idleTtl = 3600 } = {}) {
    this.absoluteTtl = absoluteTtl;
    this.idleTtl = idleTtl;
    this.sessions = new Map();
  }
  create(identity, server, scopes, now = Date.now() / 1000) {
    const token = crypto.randomBytes(32).toString("hex");
    const hash = this.hash(token);
    this.sessions.set(hash, { pid: identity.pid, name: identity.name, server, scopes: [...new Set(scopes)], created: now, last_used: now, expires: now + this.absoluteTtl });
    return { token, expires_in: this.absoluteTtl, idle_timeout: this.idleTtl };
  }
  verify(token, identity, server, scope, now = Date.now() / 1000) {
    const session = this.sessions.get(this.hash(token || ""));
    if (!session) return { ok: false, reason: "session_not_found" };
    if (now > session.expires || now - session.last_used > this.idleTtl) { this.sessions.delete(this.hash(token)); return { ok: false, reason: "session_expired" }; }
    if (session.pid !== identity.pid || session.server !== server) return { ok: false, reason: "session_binding_mismatch" };
    if (!session.scopes.includes(scope)) return { ok: false, reason: "session_scope_denied" };
    session.last_used = now;
    return { ok: true, session };
  }
  end(token, identity) {
    const hash = this.hash(token || "");
    const session = this.sessions.get(hash);
    if (!session || session.pid !== identity.pid) return false;
    this.sessions.delete(hash);
    return true;
  }
  hash(token) { return crypto.createHash("sha256").update(token).digest("hex"); }
}
module.exports = { SessionManager };
