/**
 * Shared SSE-flow helpers. The stream auth flow (mint a single-use ticket, open
 * with `?ticket=`) is security-sensitive and recently changed from `?token=`, so
 * it lives in one place instead of being re-inlined per spec.
 */
import type { Page } from '@playwright/test';
import { BASE } from './env';

/** Exchange a JWT for a single-use SSE ticket via POST /api/v1/stream/ticket. */
export async function mintSseTicket(jwt: string): Promise<string> {
  const res = await fetch(`${BASE}/api/v1/stream/ticket`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${jwt}` },
  });
  if (res.status !== 200)
    throw new Error(`mintSseTicket failed: ${res.status} ${await res.text()}`);
  return (await res.json()).ticket;
}

/** Open the SSE stream with a ticket, return the HTTP status, and tear the stream down. */
export async function openStream(ticket: string): Promise<number> {
  const c = new AbortController();
  try {
    const res = await fetch(`${BASE}/api/v1/stream?ticket=${encodeURIComponent(ticket)}`, {
      signal: c.signal,
    });
    return res.status;
  } finally {
    c.abort();
  }
}

/**
 * Count EventSource opens (GET /api/v1/stream?ticket=…) on a page — NOT the ticket
 * POST. Returns a getter for the running count.
 */
export function trackStreamOpens(page: Page): () => number {
  let n = 0;
  page.on('request', (req) => {
    if (req.method() === 'GET' && req.url().includes('/api/v1/stream?')) n++;
  });
  return () => n;
}
