/**
 * SET 42 — cache coherence + identity scrub + challenge-ban helpers.
 */
import fs from 'node:fs';
import path from 'node:path';
import { describe, expect, it } from 'vitest';
import { checkWebIdentity, FORBIDDEN } from '../scripts/check-web-identity';

const ROOT = path.resolve(import.meta.dirname, '..');

describe('SET 42d headers/redirects', () => {
  it('_headers marks /assets/* immutable and HTML shells no-store', () => {
    const h = fs.readFileSync(path.join(ROOT, 'web/public/_headers'), 'utf8');
    expect(h).toMatch(/\/assets\/\*[\s\S]*?immutable/);
    expect(h).toMatch(/\/app\n\s+Cache-Control:\s*no-store/);
    expect(h).toMatch(/\/index\.html\n\s+Cache-Control:\s*no-store/);
  });

  it('_redirects has no SPA catch-all', () => {
    const r = fs.readFileSync(path.join(ROOT, 'web/public/_redirects'), 'utf8');
    expect(r).not.toMatch(/\/\*\s+\/index\.html/);
    expect(r).not.toMatch(/\/\*\s+\/app\.html/);
    expect(r).toMatch(/\/\s+\/landing\s+200/);
  });

  it('assets Pages Function rejects HTML under /assets/*', () => {
    const src = fs.readFileSync(path.join(ROOT, 'functions/assets/[[path]].ts'), 'utf8');
    expect(src).toMatch(/text\/html/);
    expect(src).toMatch(/no-store/);
    expect(src).toMatch(/status:\s*404/);
  });
});

describe('SET 42e identity scrub', () => {
  it('landing/privacy/LICENSE no longer carry personal name or LinkedIn', () => {
    for (const rel of [
      'web/public/landing.html',
      'web/public/privacy.html',
      'web/public/LICENSE.txt',
    ]) {
      const text = fs.readFileSync(path.join(ROOT, rel), 'utf8');
      for (const re of FORBIDDEN) {
        expect(text, rel).not.toMatch(re);
      }
    }
  });

  it('landing ethos is one license sentence; epigraph sits before footer', () => {
    const html = fs.readFileSync(path.join(ROOT, 'web/public/landing.html'), 'utf8');
    expect(html).not.toMatch(/id="ethos"/);
    expect(html).not.toMatch(/strip-mined|one line you can't cross|Clone it, host it, fork it/i);
    expect(html).toMatch(/RHA Wrapper is source-available under the/);
    expect(html).toMatch(/Peacekeeping Forces/);
    expect(html).toMatch(/Beware of he who would deny you access/);
    const finalblocClose = html.lastIndexOf('</div>', html.lastIndexOf('<footer>'));
    const footerOpen = html.lastIndexOf('<footer>');
    const epiIdx = html.lastIndexOf('class="epigraph"');
    expect(epiIdx).toBeGreaterThan(finalblocClose);
    expect(epiIdx).toBeLessThan(footerOpen);
  });

  it('checkWebIdentity reports clean when dist has no forbidden strings', () => {
    // Unit-level: empty temp dir is clean (no zip → ok).
    const tmp = fs.mkdtempSync(path.join(ROOT, 'workspaces', 'set42-id-'));
    try {
      fs.writeFileSync(path.join(tmp, 'ok.html'), '<p>© 2026 rha.software</p>');
      const r = checkWebIdentity(tmp, path.join(tmp, 'missing.zip'));
      expect(r.ok).toBe(true);
      fs.writeFileSync(path.join(tmp, 'bad.html'), '<p>Andy Funke</p>');
      const bad = checkWebIdentity(tmp, path.join(tmp, 'missing.zip'));
      expect(bad.ok).toBe(false);
      expect(bad.violations.some(v => /Andy/i.test(v) || /bad\.html/.test(v))).toBe(true);
    } finally {
      fs.rmSync(tmp, { recursive: true, force: true });
    }
  });
});

describe('SET 42b challenge ban pattern', () => {
  it('edge-wait script rejects challenge bootstrap markers', () => {
    const src = fs.readFileSync(path.join(ROOT, 'scripts/edge-wait.ts'), 'utf8');
    expect(src).toMatch(/__CF\$cv\$params/);
    expect(src).toMatch(/challenge-platform/);
    expect(src).toMatch(/x-deadbeef/);
    expect(src).toMatch(/application\/javascript|javascript/);
  });
});
