import { createPrivateKey, generateKeyPairSync } from 'node:crypto';
import { buildBffSigningKey } from './bff-signing-key';

function rsaKey() {
  const { privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });
  return createPrivateKey(privateKey.export({ type: 'pkcs8', format: 'pem' }));
}

function ecKey(curve: 'prime256v1' | 'secp384r1') {
  const { privateKey } = generateKeyPairSync('ec', { namedCurve: curve });
  return createPrivateKey(privateKey.export({ type: 'pkcs8', format: 'pem' }));
}

describe('buildBffSigningKey', () => {
  it('produces a public JWK with kid + alg + use=sig from an RSA private key', async () => {
    const key = await buildBffSigningKey({
      privateKey: rsaKey(),
      kid: 'bff-2026-05',
      alg: 'RS256',
    });
    expect(key.publicJwk.kty).toBe('RSA');
    expect(key.publicJwk.kid).toBe('bff-2026-05');
    expect(key.publicJwk.alg).toBe('RS256');
    expect(key.publicJwk.use).toBe('sig');
    // No private-material leak — the public JWK must not carry `d`, `p`, `q`, `dp`, `dq`, `qi`.
    expect(key.publicJwk.d).toBeUndefined();
    expect(key.publicJwk.p).toBeUndefined();
    expect(key.publicJwk.q).toBeUndefined();
  });

  it('produces a public JWK with kty=EC + crv=P-256 for an EC P-256 key', async () => {
    const key = await buildBffSigningKey({
      privateKey: ecKey('prime256v1'),
      kid: 'bff-2026-05',
      alg: 'ES256',
    });
    expect(key.publicJwk.kty).toBe('EC');
    expect(key.publicJwk.crv).toBe('P-256');
    expect(key.publicJwk.alg).toBe('ES256');
    expect(key.publicJwk.d).toBeUndefined();
  });

  it('produces a public JWK with crv=P-384 for an EC P-384 key', async () => {
    const key = await buildBffSigningKey({
      privateKey: ecKey('secp384r1'),
      kid: 'bff-2026-05',
      alg: 'ES384',
    });
    expect(key.publicJwk.crv).toBe('P-384');
    expect(key.publicJwk.alg).toBe('ES384');
  });

  it('exposes the full original config on the returned BffSigningKey', async () => {
    const privateKey = rsaKey();
    const built = await buildBffSigningKey({ privateKey, kid: 'rotated-kid', alg: 'RS256' });
    expect(built.config.privateKey).toBe(privateKey);
    expect(built.config.kid).toBe('rotated-kid');
    expect(built.config.alg).toBe('RS256');
  });
});
