// Scratch driver for pingdotgg/t3code#18165 review finding 1: do session cookies survive an idle close?
// Run from <worktree>/apps/server: node /tmp/.../session-cookies.ts <ServerBrowserContexts.ts path> <chrome>
import { execFileSync } from "node:child_process";
import * as NodeFS from "node:fs";
import * as NodeHTTP from "node:http";
import * as NodePath from "node:path";

const [modulePath, chrome] = process.argv.slice(2);
const { ServerBrowserContexts } = await import(NodePath.resolve(modulePath!));
console.log(`module: ${modulePath}`);
const runDir = NodeFS.mkdtempSync(
  `/tmp/issue-lead-18165-r2/implement-2/run-${new Date().toISOString().replaceAll(":", "-")}-`,
);
const profilesDir = NodePath.join(runDir, "profiles");

const chromeCount = () => {
  const rows = execFileSync("ps", ["-eo", "pid,ppid,args"], { encoding: "utf8" })
    .trim()
    .split("\n")
    .slice(1)
    .map((line) => {
      const [pid, ppid, ...args] = line.trim().split(/\s+/);
      return { pid: Number(pid), ppid: Number(ppid), args: args.join(" ") };
    });
  const ours = new Set([process.pid]);
  for (let grew = true; grew; ) {
    grew = false;
    for (const row of rows)
      if (!ours.has(row.pid) && ours.has(row.ppid)) grew = Boolean(ours.add(row.pid));
  }
  return rows.filter((row) => row.pid !== process.pid && ours.has(row.pid) && row.args.includes("chrome"))
    .length;
};
const log = (line: string) => console.log(`[${new Date().toISOString()}] ${line}`);

const server = NodeHTTP.createServer((_request, response) => {
  response.setHeader("Set-Cookie", [
    "sess=1; Path=/",
    `persist=1; Path=/; Expires=${new Date(Date.now() + 86_400_000).toUTCString()}`,
  ]);
  response.end("<h1>cookies</h1>");
});
await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
const url = `http://127.0.0.1:${(server.address() as { port: number }).port}/`;

const pool = new ServerBrowserContexts({ profilesDir, executable: async () => chrome!, env: process.env });
const names = async (context: { cookies: (url: string) => Promise<{ name: string }[]> }) =>
  (await context.cookies(url)).map((cookie) => cookie.name).sort().join(",");

const first = await pool.contextFor("default");
const page = await first.newPage();
await page.goto(url);
log(`before close: cookies=${await names(first)} chrome=${chromeCount()}`);
await page.close();
await new Promise((resolve) => setTimeout(resolve, 65_000));
log(`65s after last tab closed: chrome=${chromeCount()}`);
const reopened = await pool.contextFor("default");
log(`after relaunch: cookies=${await names(reopened)} sameContext=${reopened === first}`);
await pool.clearProfile("default");
log(`after clearProfile: cookies=${await names(await pool.contextFor("default"))}`);
await pool.close();
server.close();
log(`after pool.close: chrome=${chromeCount()}`);
NodeFS.rmSync(profilesDir, { recursive: true, force: true });
