import type { CryptoBackend } from '@chat-app/shared/crypto';
import _sodium from 'libsodium-wrappers-sumo';

// Build the libsodium-backed CryptoBackend. Awaits the WASM ready-gate once,
// then returns a synchronous implementation of the CryptoBackend contract.
export async function createLibsodiumBackend(): Promise<CryptoBackend> {
  await _sodium.ready;
  const s = _sodium;

  return {
    name: 'libsodium-wrappers',
    nonceLength: s.crypto_box_NONCEBYTES,
    publicKeyLength: s.crypto_box_PUBLICKEYBYTES,
    privateKeyLength: s.crypto_box_SECRETKEYBYTES,
    secretboxKeyLength: s.crypto_secretbox_KEYBYTES,
    secretboxNonceLength: s.crypto_secretbox_NONCEBYTES,
    randomBytes: (n: number) => s.randombytes_buf(n),
    generateKeyPair: () => {
      const kp = s.crypto_box_keypair();
      return { publicKey: kp.publicKey, privateKey: kp.privateKey };
    },
    box: (plaintext, nonce, recipientPublicKey, senderPrivateKey) =>
      s.crypto_box_easy(plaintext, nonce, recipientPublicKey, senderPrivateKey),
    boxOpen: (ciphertext, nonce, senderPublicKey, recipientPrivateKey) =>
      s.crypto_box_open_easy(ciphertext, nonce, senderPublicKey, recipientPrivateKey),
    secretbox: (plaintext, nonce, key) => s.crypto_secretbox_easy(plaintext, nonce, key),
    secretboxOpen: (ciphertext, nonce, key) => s.crypto_secretbox_open_easy(ciphertext, nonce, key),
  };
}
