import { describe, test, expect } from 'bun:test';
import { readFileSync } from 'fs';
import { join } from 'path';
import {
  deriveBlobSlotId,
  deriveBlobKey,
  deriveBlobSigningSeed,
} from '../src/crypto/kdf.js';
import { ed25519PublicKeyFromSeed } from '@shade/crypto-web';

function fromHex(s: string): Uint8Array {
  const out = new Uint8Array(s.length / 2);
  for (let i = 0; i < out.length; i++) {
    out[i] = parseInt(s.substr(i * 2, 2), 16);
  }
  return out;
}

function toHex(b: Uint8Array): string {
  let s = '';
  for (const x of b) s += x.toString(16).padStart(2, '0');
  return s;
}

describe('V4.9 blob-storage KDF vectors', () => {
  // Resolve relative to this file, not to cwd, so the test passes
  // regardless of which directory `bun test` is invoked from.
  const vectorPath = join(import.meta.dir, '..', '..', '..', 'test-vectors', 'blob-storage.json');
  const vectors = JSON.parse(readFileSync(vectorPath, 'utf-8')) as {
    kdf: Array<{
      masterKey: string;
      app: string;
      slotId: string;
      blobKey: string;
      signingSeed: string;
      ownerPubkey: string;
    }>;
  };

  for (const v of vectors.kdf) {
    test(`(master=${v.masterKey.slice(0, 8)}…, app=${v.app})`, () => {
      const km = fromHex(v.masterKey);
      expect(toHex(deriveBlobSlotId(km, v.app))).toBe(v.slotId);
      expect(toHex(deriveBlobKey(km, v.app))).toBe(v.blobKey);
      const seed = deriveBlobSigningSeed(km, v.app);
      expect(toHex(seed)).toBe(v.signingSeed);
      expect(toHex(ed25519PublicKeyFromSeed(seed))).toBe(v.ownerPubkey);
    });
  }
});
