/**
 * use-privacy.test-helpers.js — pure Node-compatible helpers for privacy tests.
 *
 * These mirror the Web Worker algorithm using node:crypto so server-side tests
 * can cross-check PBKDF2 derivation and HMAC verification without importing
 * the Worker itself.
 *
 * Keep the constants in sync with privacy.worker.js and lib/privacy-defaults.js.
 */

import { pbkdf2Sync, createHmac, randomBytes, timingSafeEqual } from 'node:crypto';

// Keep in sync with lib/privacy-defaults.js
const PRIVACY_HMAC_LABEL = 'madarx-privacy-v1';
const PRIVACY_PBKDF2_ITERATIONS = 600000;

// ---------------------------------------------------------------------------
// base64url helpers (no external deps)
// ---------------------------------------------------------------------------

export function base64urlEncode(buf) {
  return Buffer.from(buf).toString('base64url');
}

export function base64urlDecode(str) {
  return Buffer.from(str, 'base64url');
}

// ---------------------------------------------------------------------------
// Core crypto helpers (Node)
// ---------------------------------------------------------------------------

/**
 * Derive 32 bytes via PBKDF2-SHA256 using node:crypto.
 * @param {string} passphrase
 * @param {Buffer|Uint8Array} salt
 * @param {number} iterations
 * @returns {Buffer}
 */
export function deriveKeySync(passphrase, salt, iterations = PRIVACY_PBKDF2_ITERATIONS) {
  return pbkdf2Sync(passphrase, salt, iterations, 32, 'sha256');
}

/**
 * Compute HMAC-SHA256 of label under the derived key.
 * @param {Buffer} keyBuf  — 32-byte derived key
 * @param {string} label
 * @returns {Buffer}
 */
export function computeHmacSync(keyBuf, label = PRIVACY_HMAC_LABEL) {
  return createHmac('sha256', keyBuf).update(label).digest();
}

/**
 * Full setup flow: generate salt, derive key, compute HMAC.
 * Returns { salt_b64, hmac_b64 } matching the shape the Worker sends back.
 *
 * @param {string} passphrase
 * @param {number} [iterations]
 * @returns {{ salt_b64: string, hmac_b64: string }}
 */
export function setupSync(passphrase, iterations = PRIVACY_PBKDF2_ITERATIONS) {
  const salt = randomBytes(16);
  const key = deriveKeySync(passphrase, salt, iterations);
  const hmac = computeHmacSync(key);
  return {
    salt_b64: base64urlEncode(salt),
    hmac_b64: base64urlEncode(hmac),
  };
}

/**
 * Verify a candidate passphrase against stored salt_b64 + hmac_b64.
 * Returns true if the passphrase is correct.
 *
 * @param {string} passphrase
 * @param {string} salt_b64
 * @param {string} hmac_b64
 * @param {number} [iterations]
 * @returns {boolean}
 */
export function verifySync(passphrase, salt_b64, hmac_b64, iterations = PRIVACY_PBKDF2_ITERATIONS) {
  const salt = base64urlDecode(salt_b64);
  const key = deriveKeySync(passphrase, salt, iterations);
  const hmac = computeHmacSync(key);
  const computed = base64urlEncode(hmac);

  const a = Buffer.from(computed);
  const b = Buffer.from(hmac_b64);
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}
