import { expect, test } from "bun:test";
import crypto from "crypto";

test("getHashes", () => {
  const nodeHashes = [
    "RSA-MD5",
    "RSA-RIPEMD160",
    "RSA-SHA1",
    "RSA-SHA1-2",
    "RSA-SHA224",
    "RSA-SHA256",
    "RSA-SHA3-224",
    "RSA-SHA3-256",
    "RSA-SHA3-384",
    "RSA-SHA3-512",
    "RSA-SHA384",
    "RSA-SHA512",
    "RSA-SHA512/224",
    "RSA-SHA512/256",
    "RSA-SM3",
    "blake2b512",
    "blake2s256",
    "id-rsassa-pkcs1-v1_5-with-sha3-224",
    "id-rsassa-pkcs1-v1_5-with-sha3-256",
    "id-rsassa-pkcs1-v1_5-with-sha3-384",
    "id-rsassa-pkcs1-v1_5-with-sha3-512",
    "md5",
    "md5-sha1",
    "md5WithRSAEncryption",
    "ripemd",
    "ripemd160",
    "ripemd160WithRSA",
    "rmd160",
    "sha1",
    "sha1WithRSAEncryption",
    "sha224",
    "sha224WithRSAEncryption",
    "sha256",
    "sha256WithRSAEncryption",
    "sha3-224",
    "sha3-256",
    "sha3-384",
    "sha3-512",
    "sha384",
    "sha384WithRSAEncryption",
    "sha512",
    "sha512-224",
    "sha512-224WithRSAEncryption",
    "sha512-256",
    "sha512-256WithRSAEncryption",
    "sha512WithRSAEncryption",
    "shake128",
    "shake256",
    "sm3",
    "sm3WithRSAEncryption",
    "ssl3-md5",
    "ssl3-sha1",
  ];

  const bunHashes = crypto.getHashes();

  for (const bunHash of bunHashes) {
    try {
      expect(nodeHashes).toContain(bunHash);
    } catch {
      console.log("bun only hash:", bunHash);
      expect(nodeHashes).not.toInclude(bunHash.toLowerCase());
      expect(nodeHashes).not.toInclude(bunHash.toUpperCase());
    }
  }
});

test("getCurves", () => {
  const nodeCurves = [
    "Oakley-EC2N-3",
    "Oakley-EC2N-4",
    "SM2",
    "brainpoolP160r1",
    "brainpoolP160t1",
    "brainpoolP192r1",
    "brainpoolP192t1",
    "brainpoolP224r1",
    "brainpoolP224t1",
    "brainpoolP256r1",
    "brainpoolP256t1",
    "brainpoolP320r1",
    "brainpoolP320t1",
    "brainpoolP384r1",
    "brainpoolP384t1",
    "brainpoolP512r1",
    "brainpoolP512t1",
    "c2pnb163v1",
    "c2pnb163v2",
    "c2pnb163v3",
    "c2pnb176v1",
    "c2pnb208w1",
    "c2pnb272w1",
    "c2pnb304w1",
    "c2pnb368w1",
    "c2tnb191v1",
    "c2tnb191v2",
    "c2tnb191v3",
    "c2tnb239v1",
    "c2tnb239v2",
    "c2tnb239v3",
    "c2tnb359v1",
    "c2tnb431r1",
    "prime192v1",
    "prime192v2",
    "prime192v3",
    "prime239v1",
    "prime239v2",
    "prime239v3",
    "prime256v1",
    "secp112r1",
    "secp112r2",
    "secp128r1",
    "secp128r2",
    "secp160k1",
    "secp160r1",
    "secp160r2",
    "secp192k1",
    "secp224k1",
    "secp224r1",
    "secp256k1",
    "secp384r1",
    "secp521r1",
    "sect113r1",
    "sect113r2",
    "sect131r1",
    "sect131r2",
    "sect163k1",
    "sect163r1",
    "sect163r2",
    "sect193r1",
    "sect193r2",
    "sect233k1",
    "sect233r1",
    "sect239k1",
    "sect283k1",
    "sect283r1",
    "sect409k1",
    "sect409r1",
    "sect571k1",
    "sect571r1",
    "wap-wsg-idm-ecid-wtls1",
    "wap-wsg-idm-ecid-wtls10",
    "wap-wsg-idm-ecid-wtls11",
    "wap-wsg-idm-ecid-wtls12",
    "wap-wsg-idm-ecid-wtls3",
    "wap-wsg-idm-ecid-wtls4",
    "wap-wsg-idm-ecid-wtls5",
    "wap-wsg-idm-ecid-wtls6",
    "wap-wsg-idm-ecid-wtls7",
    "wap-wsg-idm-ecid-wtls8",
    "wap-wsg-idm-ecid-wtls9",
  ];

  // we should only have a subset of supported node curves
  const bunCurves = crypto.getCurves();
  for (const bunCurve of bunCurves) {
    expect(nodeCurves).toContain(bunCurve);
  }
});

test("getCiphers", () => {
  const nodeCiphers = [
    "aes-128-cbc",
    "aes-128-ccm",
    "aes-128-cfb",
    "aes-128-cfb1",
    "aes-128-cfb8",
    "aes-128-ctr",
    "aes-128-ecb",
    "aes-128-gcm",
    "aes-128-ocb",
    "aes-128-ofb",
    "aes-128-xts",
    "aes-192-cbc",
    "aes-192-ccm",
    "aes-192-cfb",
    "aes-192-cfb1",
    "aes-192-cfb8",
    "aes-192-ctr",
    "aes-192-ecb",
    "aes-192-gcm",
    "aes-192-ocb",
    "aes-192-ofb",
    "aes-256-cbc",
    "aes-256-ccm",
    "aes-256-cfb",
    "aes-256-cfb1",
    "aes-256-cfb8",
    "aes-256-ctr",
    "aes-256-ecb",
    "aes-256-gcm",
    "aes-256-ocb",
    "aes-256-ofb",
    "aes-256-xts",
    "aes128",
    "aes128-wrap",
    "aes128-wrap-pad",
    "aes192",
    "aes192-wrap",
    "aes192-wrap-pad",
    "aes256",
    "aes256-wrap",
    "aes256-wrap-pad",
    "aria-128-cbc",
    "aria-128-ccm",
    "aria-128-cfb",
    "aria-128-cfb1",
    "aria-128-cfb8",
    "aria-128-ctr",
    "aria-128-ecb",
    "aria-128-gcm",
    "aria-128-ofb",
    "aria-192-cbc",
    "aria-192-ccm",
    "aria-192-cfb",
    "aria-192-cfb1",
    "aria-192-cfb8",
    "aria-192-ctr",
    "aria-192-ecb",
    "aria-192-gcm",
    "aria-192-ofb",
    "aria-256-cbc",
    "aria-256-ccm",
    "aria-256-cfb",
    "aria-256-cfb1",
    "aria-256-cfb8",
    "aria-256-ctr",
    "aria-256-ecb",
    "aria-256-gcm",
    "aria-256-ofb",
    "aria128",
    "aria192",
    "aria256",
    "camellia-128-cbc",
    "camellia-128-cfb",
    "camellia-128-cfb1",
    "camellia-128-cfb8",
    "camellia-128-ctr",
    "camellia-128-ecb",
    "camellia-128-ofb",
    "camellia-192-cbc",
    "camellia-192-cfb",
    "camellia-192-cfb1",
    "camellia-192-cfb8",
    "camellia-192-ctr",
    "camellia-192-ecb",
    "camellia-192-ofb",
    "camellia-256-cbc",
    "camellia-256-cfb",
    "camellia-256-cfb1",
    "camellia-256-cfb8",
    "camellia-256-ctr",
    "camellia-256-ecb",
    "camellia-256-ofb",
    "camellia128",
    "camellia192",
    "camellia256",
    "chacha20",
    "chacha20-poly1305",
    "des-ede",
    "des-ede-cbc",
    "des-ede-cfb",
    "des-ede-ecb",
    "des-ede-ofb",
    "des-ede3",
    "des-ede3-cbc",
    "des-ede3-cfb",
    "des-ede3-cfb1",
    "des-ede3-cfb8",
    "des-ede3-ecb",
    "des-ede3-ofb",
    "des3",
    "des3-wrap",
    "id-aes128-CCM",
    "id-aes128-GCM",
    "id-aes128-wrap",
    "id-aes128-wrap-pad",
    "id-aes192-CCM",
    "id-aes192-GCM",
    "id-aes192-wrap",
    "id-aes192-wrap-pad",
    "id-aes256-CCM",
    "id-aes256-GCM",
    "id-aes256-wrap",
    "id-aes256-wrap-pad",
    "id-smime-alg-CMS3DESwrap",
    "sm4",
    "sm4-cbc",
    "sm4-cfb",
    "sm4-ctr",
    "sm4-ecb",
    "sm4-ofb",
  ];

  const bunCiphers = crypto.getCiphers();
  for (const bunCipher of bunCiphers) {
    try {
      expect(nodeCiphers).toContain(bunCipher);
    } catch {
      console.log("bun only cipher:", bunCipher);
      expect(nodeCiphers).not.toContain(bunCipher.toLowerCase());
      expect(nodeCiphers).not.toContain(bunCipher.toUpperCase());
    }
  }
});
