// Tests for the ephemeral sessions the subscription background processor
// mints to run /api/process AS each item's owner (per-tenant subscriptions,
// step 4). The mechanism reuses the real sessions table, so verifying the
// row it writes is valid + non-expired (and gets cleaned up) is enough to
// trust the existing cookie → tenant-auth → req.user chain.

import { test, describe, before, after } from "node:test";
import { strict as assert } from "node:assert";
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";

import { initDb, getDb, closeDb } from "../db.js";
import {
  mintInternalSession,
  deleteInternalSession,
  adminUserId,
} from "../auth-routes.js";

let dataDir;

function makeUser({ id, email, isAdmin = 0 }) {
  getDb()
    .prepare(
      `INSERT INTO users (id, email, created_at, synthetic_install_id, is_admin)
       VALUES (?, ?, ?, ?, ?)`,
    )
    .run(id, email, Date.now(), `inst-${id}`, isAdmin);
}

before(async () => {
  dataDir = mkdtempSync(path.join(tmpdir(), "recap-sess-"));
  await initDb({ dataDir });
});

after(() => {
  closeDb();
  rmSync(dataDir, { recursive: true, force: true });
});

describe("mintInternalSession / deleteInternalSession", () => {
  test("creates a valid, non-expired session row for the user", () => {
    makeUser({ id: "u-tenant", email: "tenant@example.com" });
    const token = mintInternalSession("u-tenant");
    assert.ok(typeof token === "string" && token.length > 20);

    // Looks up exactly like tenant-auth does: by id, must be unexpired.
    const row = getDb()
      .prepare("SELECT * FROM sessions WHERE id = ? AND expires_at > ?")
      .get(token, Date.now());
    assert.ok(row, "session row exists and is not expired");
    assert.equal(row.user_id, "u-tenant");
    assert.ok(row.expires_at > Date.now(), "expires in the future");
  });

  test("deleteInternalSession removes the row (no lingering identity)", () => {
    makeUser({ id: "u-temp", email: "temp@example.com" });
    const token = mintInternalSession("u-temp");
    assert.ok(getDb().prepare("SELECT 1 FROM sessions WHERE id = ?").get(token));
    deleteInternalSession(token);
    assert.equal(
      getDb().prepare("SELECT 1 FROM sessions WHERE id = ?").get(token),
      undefined,
    );
  });

  test("deleteInternalSession tolerates null / unknown tokens", () => {
    // Should not throw.
    deleteInternalSession(null);
    deleteInternalSession("does-not-exist");
  });
});

describe("adminUserId", () => {
  test("returns the operator (is_admin = 1) user id", () => {
    makeUser({ id: "u-admin", email: "admin@example.com", isAdmin: 1 });
    assert.equal(adminUserId(), "u-admin");
  });
});
