/**
 * Regression for the review's CR2: export archives (Gallery.zip / Memories.zip)
 * were written under media_path/exports, and /media is a public ServeDir — so
 * anyone could GET /media/exports/Gallery.zip and download the whole gallery,
 * bypassing the ticket + export_*_ready gate. Exports now live OUTSIDE media_path
 * and are reachable only via the gated /api/v1/export/{zip,html} handlers.
 *
 * This drives a REAL export (release → job runs → archive on disk) and then
 * asserts the archive is NOT public but IS gated. Asserting a 404 on an empty
 * stack would pass even if exports were still under /media (the file just wouldn't
 * exist yet) — so we produce a real file first, then prove it can't leak.
 */
import { test, expect } from '../../fixtures/test';
import { seedUpload } from '../../helpers/seed';
import { BASE } from '../../helpers/env';

test.describe('Export — no public leak (CR2)', () => {
  test('a real export is downloadable only via the gated endpoint, never via /media', async ({
    host,
  }) => {
    test.setTimeout(60_000);
    const bearer = { Authorization: `Bearer ${host.jwt}` };

    // Seed content so the archive actually contains a file.
    await seedUpload(host.jwt, { caption: 'in the export' });

    // Host releases the gallery → spawns the real zip/html export jobs.
    const rel = await fetch(`${BASE}/api/v1/host/gallery/release`, {
      method: 'POST',
      headers: bearer,
    });
    expect(rel.status).toBe(204);

    // Wait for the real zip job to finish writing the archive to disk.
    await expect
      .poll(
        async () => {
          const res = await fetch(`${BASE}/api/v1/export/status`, { headers: bearer });
          return (await res.json()).zip?.status;
        },
        { timeout: 45_000, intervals: [500] }
      )
      .toBe('done');

    // The archive now EXISTS on disk. It must NOT be reachable via public /media…
    for (const name of ['Gallery.zip', 'Memories.zip']) {
      const leak = await fetch(`${BASE}/media/exports/${name}`);
      // A 200 here = the whole-gallery archive is downloadable with no auth (CR2).
      expect(leak.status, `${name} must not be served from public /media`).toBe(404);
    }

    // …but IS retrievable via the gated single-use ticket endpoint. This proves the
    // 404 above means "not public", not merely "no file was produced".
    const ticketRes = await fetch(`${BASE}/api/v1/export/ticket?kind=zip`, {
      method: 'POST',
      headers: bearer,
    });
    const { ticket } = await ticketRes.json();
    const dl = await fetch(`${BASE}/api/v1/export/zip?ticket=${encodeURIComponent(ticket)}`);
    expect(dl.status).toBe(200);
    // Real ZIP payload: the archive starts with the PK local-file-header magic.
    const head = new Uint8Array(await dl.arrayBuffer()).subarray(0, 2);
    expect(Array.from(head)).toEqual([0x50, 0x4b]); // "PK"
  });
});
