/**
 * Regression guard — the host is warned about storage BEFORE it becomes unrecoverable.
 *
 * Storage visibility used to exist in exactly one place: a passive "Speicherauslastung" widget on
 * the ADMIN dashboard. A host who isn't the admin had no view of it at all, and nothing anywhere
 * warned anyone. README listed a low-disk alert under "Planned (v1.x)".
 *
 * Two things make that a safety net rather than a nice-to-have:
 *
 *  - `postgres_data`, `media_data` and `exports_data` are all Docker named volumes on ONE
 *    filesystem. A full disk doesn't degrade a subsystem; Postgres stops being able to write and
 *    the whole event goes down.
 *  - The keepsake needs room for TWO gallery-sized archives (both write their media
 *    `Compression::Stored`; `Memories.zip` streams the original for every video and every image
 *    at or under 5 MB). The export preflight can refuse cleanly, but only AFTER the release —
 *    when the event is over, the gallery is full, and every remedy is harder.
 *
 * So the threshold is deliberately NOT a fixed number alone. It fires on an absolute floor (10 GB,
 * the figure the README always carried) OR on "you could not build the keepsake right now", which
 * is the trigger a host can still act on.
 *
 * These drive it through `original_size_bytes` rather than a genuinely full disk: the estimate is
 * pure SQL over that column, so overstating one row moves the accounting the warning reads without
 * touching a byte on disk.
 */
import { test, expect } from '../../fixtures/test';
import { seedUpload } from '../../helpers/seed';
import { BASE } from '../../helpers/env';

/** Comfortably larger than any disk this suite could run on. */
const ABSURD_BYTES = 500_000_000_000_000;

test.describe('Host — low-disk warning', () => {
  test('a gallery too big to export warns the host, with the numbers', async ({
    page,
    host,
    guest,
    signIn,
    db,
  }) => {
    const g = await guest('BigShooter');
    const uploadId = await seedUpload(g.jwt);
    await db.setUploadSizeBytes(uploadId, ABSURD_BYTES);

    await signIn(page, host);
    await page.goto('/host');

    const warning = page.getByTestId('low-disk-warning');
    await expect(warning, 'the host must be warned before releasing').toBeVisible({
      timeout: 15_000,
    });
    // The actionable half: not just "low", but "the keepsake cannot be built".
    await expect(warning).toContainText(/nicht.*erstellt werden/i);
    // And the consequence that makes it urgent — the event, not just the download.
    await expect(warning).toContainText(/gesamte Event/i);
  });

  test('the API reports the requirement and the verdict together', async ({ host, guest, db }) => {
    const g = await guest('BigShooter2');
    const uploadId = await seedUpload(g.jwt);
    await db.setUploadSizeBytes(uploadId, ABSURD_BYTES);

    const res = await fetch(`${BASE}/api/v1/host/event`, {
      headers: { Authorization: `Bearer ${host.jwt}` },
    });
    expect(res.status).toBe(200);
    const body = (await res.json()) as {
      disk_low: boolean;
      disk_free_bytes: number | null;
      keepsake_required_bytes: number;
    };

    expect(body.disk_low).toBe(true);
    expect(
      body.keepsake_required_bytes,
      'both halves are armed by a release, so the requirement covers two archives'
    ).toBeGreaterThan(ABSURD_BYTES);
    expect(body.disk_free_bytes).not.toBeNull();
    expect(body.keepsake_required_bytes).toBeGreaterThan(body.disk_free_bytes!);
  });

  test('an ordinary gallery shows no warning at all', async ({ page, host, guest, signIn }) => {
    // The mirror that keeps the above honest. A warning that is always on is a warning nobody
    // reads — and it would sit at the very top of the dashboard, above the PIN-reset queue.
    const g = await guest('NormalShooter');
    await seedUpload(g.jwt);

    await signIn(page, host);
    await page.goto('/host');

    // Wait for the dashboard to actually be loaded before asserting on an absence.
    await expect(page.getByRole('heading', { name: 'Host-Dashboard' })).toBeVisible({
      timeout: 15_000,
    });
    await expect(page.getByTestId('low-disk-warning')).toHaveCount(0);
  });
});
