/**
 * test-passkey-signer.ts — Test the passkey x402 signer module.
 *
 * Verifies that createPasskeySigner() and createPasskeySignerFromKeys()
 * work correctly with simulated PRF output. Does NOT make actual payments
 * (that requires a funded wallet + live facilitator).
 *
 * Usage:
 *   bun run scripts/test-passkey-signer.ts
 */

import { createPasskeySigner, createPasskeySignerFromKeys } from '../shared/x402/passkey-signer';
import { deriveEOAFromPRF } from '../src/encryptid/eoa-derivation';
import { EncryptIDKeyManager, type DerivedKeys } from '../src/encryptid/key-derivation';

let passed = 0;
let failed = 0;

function assert(condition: boolean, msg: string) {
  if (condition) {
    console.log(`  ✓ ${msg}`);
    passed++;
  } else {
    console.error(`  ✗ ${msg}`);
    failed++;
  }
}

async function main() {
  console.log('=== Passkey Signer Tests ===\n');

  // Fixed PRF output
  const prfOutput = new Uint8Array(32);
  for (let i = 0; i < 32; i++) prfOutput[i] = i + 1;

  // Expected EOA from this PRF
  const expectedEOA = deriveEOAFromPRF(prfOutput);

  // Test 1: createPasskeySigner from raw PRF
  console.log('[1] createPasskeySigner (from raw PRF)');
  const signer = await createPasskeySigner({ prfOutput });
  assert(signer.eoaAddress === expectedEOA.address, 'EOA address matches derivation');
  assert(typeof signer.paidFetch === 'function', 'paidFetch is a function');
  assert(typeof signer.cleanup === 'function', 'cleanup is a function');
  console.log(`  EOA: ${signer.eoaAddress}`);

  // Test 2: Cleanup zeros the key
  console.log('\n[2] Cleanup');
  signer.cleanup();
  // Can't directly check the internal state, but we verify it doesn't throw
  assert(true, 'Cleanup ran without error');

  // Test 3: createPasskeySignerFromKeys (from DerivedKeys)
  console.log('\n[3] createPasskeySignerFromKeys');
  const km = new EncryptIDKeyManager();
  await km.initFromPRF(prfOutput.buffer);
  const keys = await km.getKeys();

  const signer2 = await createPasskeySignerFromKeys(keys);
  assert(signer2 !== null, 'Signer created from DerivedKeys');
  assert(signer2!.eoaAddress === expectedEOA.address, 'Same EOA address from keys');
  assert(typeof signer2!.paidFetch === 'function', 'paidFetch is a function');
  signer2!.cleanup();

  // Test 4: createPasskeySignerFromKeys returns null for passphrase keys
  console.log('\n[4] Returns null for passphrase-derived keys (no EOA)');
  const km2 = new EncryptIDKeyManager();
  await km2.initFromPassphrase('test-pass', new Uint8Array(32));
  const passKeys = await km2.getKeys();
  const signer3 = await createPasskeySignerFromKeys(passKeys);
  assert(signer3 === null, 'Returns null when no EOA keys');
  km2.clear();

  // Test 5: Custom network
  console.log('\n[5] Custom network');
  const signer4 = await createPasskeySigner({
    prfOutput,
    network: 'eip155:8453',  // Base mainnet
  });
  assert(signer4.eoaAddress === expectedEOA.address, 'Same EOA regardless of network');
  signer4.cleanup();

  // Cleanup
  km.clear();

  console.log(`\n=== Results: ${passed} passed, ${failed} failed ===`);
  process.exit(failed > 0 ? 1 : 0);
}

main().catch(err => {
  console.error('Fatal:', err);
  process.exit(1);
});
