// fixtures.js — canned LSB payloads and fake DB rows that exercise all
// 9 Verdict Table Pathways terminals.
//
// The steg_id values are canonical 32-hex lowercase — EXACTLY what the
// Dart signer writes into the LSB payload string as
// `"${params.stegId}|${params.creatorId}"` where params.stegId is
// initResp.stegId (a 32-hex string from routers/sign.py /sign/init).

'use strict';

const { TextEncoder } = require('util');
const enc = new TextEncoder();

// ─── Fake /sign/init responses that drive each fixture ──────────────────────
const STEG_A = '02bcd7da4a6f79b72e5c4bca7c81bfa3';  // 32-hex lowercase
const STEG_B = 'f9a38b6d1e4c5a027d88ccb61c07f3e1';
const STEG_C = '1122334455667788aabbccddeeff0011';
const STEG_D = '0011223344556677889900aabbccddee';

const CREATOR_U = 'cd336016-ec30-43a5-9893-a387f827cf08';  // dashed uuid
const CREATOR_V = '11111111-2222-3333-4444-555555555555';

// 64-hex fake post-sign BLAKE3 hashes
const HASH_A = 'aa'.repeat(32);
const HASH_B = 'bb'.repeat(32);
const HASH_C = 'cc'.repeat(32);
const HASH_D = 'dd'.repeat(32);

// 16-hex dhash pHashes (64-bit)
const PH_A = '0f0f0f0f0f0f0f0f';
const PH_B = 'ffffffffffffffff';  // very far from A
const PH_A_CLOSE = '0f0f0f0f0f0f0f1f';  // 1 bit diff — within threshold
const PH_C = 'a5a5a5a5a5a5a5a5';
const PH_D = '5a5a5a5a5a5a5a5a';  // far from all

// ─── LSB payloads the extension actually sees (UTF-8 bytes of the string) ──
function lsb(stegIdStr, creatorId, preSignHash) {
  let s = stegIdStr + '|' + creatorId;
  if (preSignHash) s += '|' + preSignHash;
  return enc.encode(s);
}

// Fixtures
const FIXTURES = [
  // 1. signed — canonical case. Authentic.
  {
    name: 'signed_authentic',
    expected: { terminal: 1, verdict: 'authentic' },
    input: {
      lsbPayload: lsb(STEG_A, CREATOR_U),
      pHash: PH_A,
      fileBlake3: HASH_A,
      meta: null,
    },
  },
  // 2. altered — signed, then pixel flipped. Same steg_id, wrong hash.
  //    pHash still close enough → TRANSFORMED (5) if close, or ALTERED(2) if far
  {
    name: 'altered_same_creator',
    expected: { terminal: 2, verdict: 'altered' },
    input: {
      lsbPayload: lsb(STEG_B, CREATOR_U),
      pHash: '0000000000000000',  // far from the stored PH_B
      fileBlake3: 'ee'.repeat(32), // wrong hash
      meta: null,
    },
  },
  // 3. resigned — different user re-signed the same visual content.
  //    fast-path must MISS (hash differs from any DB row). LSB extraction
  //    recovers STEG_C with CREATOR_V. Server says STEG_C belongs to
  //    CREATOR_U, so the mismatch is RESIGNED if hash still matches
  //    post_sign_hash after the wrapper re-encode. We model that by
  //    giving the extracted fixture a DIFFERENT file hash (what the
  //    browser saw) but having the server's verify look up by steg_id
  //    only — resigned is detected when LSB creator != DB creator AND
  //    the new file is hash-bytewise equal to the re-signed output. In
  //    this mock we trigger resigned by content_hash == row.post_sign_hash
  //    WITH extracted_creator_id != row.creator_id, bypassing fast-path
  //    by making the FILE HASH the extension computes differ from the
  //    DB row (hence the 'cc...' sentinel is NOT in DB_RECORDS below).
  {
    name: 'resigned_different_creator',
    expected: { terminal: 3, verdict: 'resigned' },
    input: {
      lsbPayload: lsb(STEG_C, CREATOR_V),  // wrong creator in LSB vs DB
      pHash: PH_C,
      fileBlake3: HASH_C,                  // matches post_sign_hash in DB
      meta: null,
    },
    // Force fast-path to miss for this fixture by marking as no-fast.
    disableFastPath: true,
  },
  // 4. creator mismatch — LSB says different creator AND hash differs.
  {
    name: 'creator_mismatch',
    expected: { terminal: 4, verdict: 'creator_mismatch' },
    input: {
      lsbPayload: lsb(STEG_C, CREATOR_V),
      pHash: PH_C,
      fileBlake3: 'ee'.repeat(32),
      meta: null,
    },
  },
  // 5. transformed — recompressed. pHash close, hash different.
  {
    name: 'transformed',
    expected: { terminal: 5, verdict: 'transformed' },
    input: {
      lsbPayload: lsb(STEG_A, CREATOR_U),
      pHash: PH_A_CLOSE,
      fileBlake3: 'ff'.repeat(32),
      meta: null,
    },
  },
  // 6. unknown, pHash close to an altered row — LSB missing entirely.
  {
    name: 'unknown_similar_to_altered',
    expected: { terminal: 6, verdict: 'unknown' },
    input: {
      lsbPayload: null,
      pHash: PH_B,
      fileBlake3: 'cafe'.repeat(16),
      meta: null,
    },
  },
  // 7. unknown, pHash close to authentic.
  {
    name: 'unknown_similar_to_authentic',
    expected: { terminal: 7, verdict: 'unknown' },
    input: {
      lsbPayload: null,
      pHash: PH_A_CLOSE,
      fileBlake3: 'beef'.repeat(16),
      meta: null,
    },
  },
  // 8. totally unknown — no LSB, pHash far from all DB rows.
  //    0xAA repeating has Hamming distance >= 32 from every DB pHash.
  {
    name: 'unknown',
    expected: { terminal: 8, verdict: 'unknown' },
    input: {
      lsbPayload: null,
      pHash: 'aaaaaaaaaaaaaaaa',
      fileBlake3: 'dead'.repeat(16),
      meta: null,
    },
  },
  // 9. LEGACY COMPAT — the LSB payload carries a dashed-UUID stegId
  //    (pre-v5.5.93 binary still floating around). Fix must still accept.
  {
    name: 'legacy_dashed_uuid',
    expected: { terminal: 1, verdict: 'authentic' },
    input: {
      // STEG_A expressed as a 36-char dashed UUID
      lsbPayload: lsb('02bcd7da-4a6f-79b7-2e5c-4bca7c81bfa3', CREATOR_U),
      pHash: PH_A,
      fileBlake3: HASH_A,
      meta: null,
    },
  },
];

// ─── Server-side fake DB that matches the above ────────────────────────────
// STEG_B is flagged altered (a user reported it).
const DB_RECORDS = [
  { steg_id: STEG_A, creator_id: CREATOR_U, post_sign_hash: HASH_A, pHash: PH_A, altered: false },
  { steg_id: STEG_B, creator_id: CREATOR_U, post_sign_hash: HASH_B, pHash: PH_B, altered: true },
  { steg_id: STEG_C, creator_id: CREATOR_U, post_sign_hash: HASH_C, pHash: PH_C, altered: false },
  { steg_id: STEG_D, creator_id: CREATOR_V, post_sign_hash: HASH_D, pHash: PH_D, altered: false },
];

module.exports = { FIXTURES, DB_RECORDS,
  STEG_A, STEG_B, STEG_C, STEG_D, CREATOR_U, CREATOR_V };
