const { subtle } = globalThis.crypto;

const RSA_KEY_GEN = {
  modulusLength: 2048,
  publicExponent: new Uint8Array([1, 0, 1])
};

const [ECDH, X25519] = await Promise.all([
  subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, false, ['deriveBits', 'deriveKey']),
  subtle.generateKey('X25519', false, ['deriveBits', 'deriveKey']),
]);

const boringSSL = process.features.openssl_is_boringssl;

export const vectors = {
  'encrypt': [
    [false, 'Invalid'],
    [false, 'Ed25519'],
    [true, { name: 'AES-CBC', iv: Buffer.alloc(16) }],
    [false, 'AES-CBC'],
    [true, { name: 'AES-GCM', iv: Buffer.alloc(12) }],
    [false, 'AES-GCM'],
    [true, { name: 'AES-CTR', counter: Buffer.alloc(16), length: 128 }],
    [false, 'AES-CTR'],
    [true, 'RSA-OAEP'],
    [true, { name: 'RSA-OAEP', label: Buffer.alloc(0) }],
    [true, 'RSA-OAEP'],
    [false, { name: 'RSA-OAEP', label: null }],
  ],
  'sign': [
    [false, 'Invalid'],
    [false, 'SHA-1'],

    [true, 'Ed25519'],

    [true, 'RSASSA-PKCS1-v1_5'],

    [true, { name: 'RSA-PSS', saltLength: 32 }],
    [false, 'RSA-PSS'],

    [true, { name: 'ECDSA', hash: 'SHA-256' }],
    [false, { name: 'ECDSA', hash: 'Invalid' }],
    [false, { name: 'ECDSA', hash: 'Ed25519' }],
    [false, 'ECDSA'],

    [true, 'HMAC'],
  ],
  'digest': [
    [true, 'SHA-1'],
    [true, 'SHA-256'],
    [true, 'SHA-384'],
    [true, 'SHA-512'],
    [false, 'Invalid'],
    [false, 'Ed25519'],
  ],
  'generateKey': [
    [false, 'SHA-1'],
    [false, 'Invalid'],
    [false, 'HKDF'],
    [false, 'PBKDF2'],
    [true, 'X25519'],
    [true, 'Ed25519'],
    [true, { name: 'HMAC', hash: 'SHA-256' }],
    [true, { name: 'HMAC', hash: 'SHA-256', length: 256 }],
    [true, { name: 'HMAC', hash: 'SHA-256', length: 25 }],
    [true, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256', ...RSA_KEY_GEN }],
    [true, { name: 'RSA-PSS', hash: 'SHA-256', ...RSA_KEY_GEN }],
    [true, { name: 'RSA-OAEP', hash: 'SHA-256', ...RSA_KEY_GEN }],
    [true, { name: 'ECDSA', namedCurve: 'P-256' }],
    [false, { name: 'ECDSA', namedCurve: 'X25519' }],
    [true, { name: 'AES-CTR', length: 128 }],
    [false, { name: 'AES-CTR', length: 25 }],
    [true, { name: 'AES-CBC', length: 128 }],
    [false, { name: 'AES-CBC', length: 25 }],
    [true, { name: 'AES-GCM', length: 128 }],
    [false, { name: 'AES-GCM', length: 25 }],
    [true, { name: 'AES-KW', length: 128 }],
    [false, { name: 'AES-KW', length: 25 }],
    [true, { name: 'HMAC', hash: 'SHA-256' }],
    [true, { name: 'HMAC', hash: 'SHA-256', length: 256 }],
    [true, { name: 'HMAC', hash: 'SHA-256', length: 25 }],
    [false, { name: 'HMAC', hash: 'SHA-256', length: 0 }],
  ],
  'deriveKey': [
    [true,
     { name: 'HKDF', hash: 'SHA-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) },
     { name: 'AES-CBC', length: 128 }],
    [true,
     { name: 'HKDF', hash: 'SHA-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) },
     { name: 'HMAC', hash: 'SHA-256' }],
    [false,
     { name: 'HKDF', hash: 'SHA-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) },
     'HKDF'],
    [true,
     { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 },
     { name: 'AES-CBC', length: 128 }],
    [true,
     { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 },
     { name: 'HMAC', hash: 'SHA-256' }],
    [false,
     { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 },
     'HKDF'],
    [true,
     { name: 'X25519', public: X25519.publicKey },
     { name: 'AES-CBC', length: 128 }],
    [false,
     { name: 'X25519', public: X25519.publicKey },
     { name: 'HMAC', hash: 'SHA-256' }],
    [true,
     { name: 'X25519', public: X25519.publicKey },
     { name: 'HMAC', hash: 'SHA-256', length: 256 }],
    [false,
     { name: 'X25519', public: X25519.publicKey },
     { name: 'HMAC', hash: 'SHA-256', length: 257 }],
    [true,
     { name: 'X25519', public: X25519.publicKey },
     'HKDF'],
    [true,
     { name: 'ECDH', public: ECDH.publicKey },
     { name: 'AES-CBC', length: 128 }],
    [false,
     { name: 'ECDH', public: ECDH.publicKey },
     { name: 'HMAC', hash: 'SHA-256' }],
    [true,
     { name: 'ECDH', public: ECDH.publicKey },
     { name: 'HMAC', hash: 'SHA-256', length: 255 }],
    [true,
     { name: 'ECDH', public: ECDH.publicKey },
     { name: 'HMAC', hash: 'SHA-256', length: 256 }],
    [false,
     { name: 'ECDH', public: ECDH.publicKey },
     { name: 'HMAC', hash: 'SHA-256', length: 257 }],
    [false,
     { name: 'ECDH', public: ECDH.publicKey },
     { name: 'HMAC', hash: 'SHA-256', length: 264 }],
    [true,
     { name: 'ECDH', public: ECDH.publicKey },
     'HKDF'],
    [false,
      { name: 'X25519', public: X25519.publicKey },
      'SHA-256'],
    [false,
      { name: 'X25519', public: X25519.publicKey },
      'AES-CBC'],
  ],
  'deriveBits': [
    [true, { name: 'HKDF', hash: 'SHA-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 8],
    [true, { name: 'HKDF', hash: 'SHA-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 0],
    [false, { name: 'HKDF', hash: 'SHA-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, null],
    [false, { name: 'HKDF', hash: 'SHA-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 7],
    [false, { name: 'HKDF', hash: 'Invalid', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 8],
    [false, { name: 'HKDF', hash: 'Ed25519', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 8],

    [true, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 }, 8],
    [true, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 }, 0],
    [false, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 0 }, 8],
    [false, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 }, null],
    [false, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 }, 7],
    [false, { name: 'PBKDF2', hash: 'Invalid', salt: Buffer.alloc(0), iterations: 1 }, 8],
    [false, { name: 'PBKDF2', hash: 'Ed25519', salt: Buffer.alloc(0), iterations: 1 }, 8],

    [true,
     { name: 'ECDH', public: ECDH.publicKey }],
    [true,
     { name: 'ECDH', public: ECDH.publicKey }, 256],
    [false,
     { name: 'ECDH', public: ECDH.publicKey }, 257],
    [false,
     { name: 'ECDH', public: ECDH.publicKey }, 264],
    [false, { name: 'ECDH', public: ECDH.privateKey }],
    [false, 'ECDH'],

    [true, { name: 'X25519', public: X25519.publicKey }],
    [true, { name: 'X25519', public: X25519.publicKey }, 256],
    [false, { name: 'X25519', public: X25519.publicKey }, 257],
    [false, { name: 'X25519', public: X25519.privateKey }],
    [false, 'X25519'],
  ],
  'importKey': [
    [false, 'SHA-1'],
    [false, 'Invalid'],
    [true, 'X25519'],
    [true, 'Ed25519'],
    [true, { name: 'HMAC', hash: 'SHA-256' }],
    [true, { name: 'HMAC', hash: 'SHA-256', length: 256 }],
    [true, { name: 'HMAC', hash: 'SHA-256', length: 25 }],
    [true, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256', ...RSA_KEY_GEN }],
    [true, { name: 'RSA-PSS', hash: 'SHA-256', ...RSA_KEY_GEN }],
    [true, { name: 'RSA-OAEP', hash: 'SHA-256', ...RSA_KEY_GEN }],
    [true, { name: 'ECDSA', namedCurve: 'P-256' }],
    [false, { name: 'ECDSA', namedCurve: 'X25519' }],
    [true, 'AES-CTR'],
    [true, 'AES-CBC'],
    [true, 'AES-GCM'],
    [true, 'AES-KW'],
    [true, { name: 'HMAC', hash: 'SHA-256' }],
    [true, { name: 'HMAC', hash: 'SHA-256', length: 256 }],
    [true, { name: 'HMAC', hash: 'SHA-256', length: 25 }],
    [false, { name: 'HMAC', hash: 'SHA-256', length: 0 }],
    [true, 'HKDF'],
    [true, 'PBKDF2'],
  ],
  'exportKey': [
    [false, 'SHA-1'],
    [false, 'Invalid'],
    [false, 'HKDF'],
    [false, 'PBKDF2'],
    [true, 'RSASSA-PKCS1-v1_5'],
    [true, 'RSA-PSS'],
    [true, 'RSA-OAEP'],
    [true, 'ECDSA'],
    [true, 'ECDH'],
    [true, 'HMAC'],
    [true, 'AES-CTR'],
    [true, 'AES-CBC'],
    [true, 'AES-GCM'],
    [true, 'AES-KW'],
    [true, 'Ed25519'],
    [true, 'X25519'],
  ],
  'wrapKey': [
    [false, 'AES-KW'],
    [true, 'AES-KW', 'AES-CTR'],
    [true, 'AES-KW', 'HMAC'],
  ],
  'unwrapKey': [
    [false, 'AES-KW'],
    [true, 'AES-KW', 'AES-CTR'],
  ],
  'unsupported operation': [
    [false, ''],
    [false, 'Ed25519'],
  ],
  'get key length': [
    [false, { name: 'HMAC', hash: 'SHA-256' }],
  ],
};
