import type {
  Jwk,
  CryptoApi as OldCryptoApi,
  KeyWrapper,
  SignParams,
  DigestParams,
  VerifyParams,
  GenerateKeyParams,
  GetPublicKeyParams,
  Cipher,
} from '@web5/crypto';

import type { KeyConverter } from './key-converter.js';
import type { AsymmetricKeyConverter } from './key-converter.js';
import type { KeyBytesDeriver, KeyDeriver } from './key-deriver.js';
import type { BytesToPrivateKeyParams, BytesToPublicKeyParams, CipherParams, DeriveKeyBytesParams, DeriveKeyParams, PrivateKeyToBytesParams, PublicKeyToBytesParams, UnwrapKeyParams, WrapKeyParams } from './params-direct.js';

/**
 * The `DsaApi` interface integrates key generation, hashing, and signing functionalities,
 * designed for use with a Key Management System (KMS). It extends `AsymmetricKeyGenerator` for
 * generating asymmetric keys, `Hasher` for hash digest computations, and `Signer` for signing and
 * verifying operations.
 *
 * Concrete implementations of this interface are intended to be used with a KMS, which is
 * responsible for generating and storing cryptographic keys. The KMS is also responsible for
 * performing cryptographic operations using the keys it manages. The KMS is typically a cloud
 * service, but it can also be a hardware device or software application.
 *
 * Guidelines for implementing this interface:
 * - Must use JSON Web Keys ({@link Jwk | JWK}) as the key format.
 * - Must IANA registered JSON Object Signing and Encryption
 *   {@ link https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms | (JOSE)}
 *   names for algorithm, curves, etc. whenever possible.
 * - All I/O that interacts with private or secret keys must be done via reference using a
 *   {@link KeyIdentifier | `KeyIdentifier`}. Implementations can use any string as the key
 *   identifier (e.g. JWK thumbprint, UUID generated by hosted KMS, etc.).
 * - Must support key generation, hashing, signing, and verifying operations.
 * - May be extended to support other cryptographic operations.
 * - Implementations of the `DsaApi` interface can be passed as an argument to the public API
 *   methods of Web5 libraries that involve key material (e.g., DID creation, VC signing, arbitrary
 *   data signing/verification, etc.).
 */
export interface DsaApi<
  GenerateKeyInput = GenerateKeyParams,
  GenerateKeyOutput = Jwk,
  GetPublicKeyInput = GetPublicKeyParams,
  DigestInput = DigestParams,
  SignInput = SignParams,
  VerifyInput = VerifyParams
> extends OldCryptoApi<GenerateKeyInput, GenerateKeyOutput, GetPublicKeyInput, DigestInput, SignInput, VerifyInput> {}

export interface CryptoApi<
  GenerateKeyInput = GenerateKeyParams,
  GenerateKeyOutput = Jwk,
  GetPublicKeyInput = GetPublicKeyParams,
  DigestInput = DigestParams,
  SignInput = SignParams,
  VerifyInput = VerifyParams,
  EncryptInput = CipherParams,
  DecryptInput = CipherParams,
  BytesToPublicKeyInput = BytesToPublicKeyParams,
  PublicKeyToBytesInput = PublicKeyToBytesParams,
  BytesToPrivateKeyInput = BytesToPrivateKeyParams,
  PrivateKeyToBytesInput = PrivateKeyToBytesParams,
  DeriveKeyInput = DeriveKeyParams,
  DeriveKeyOutput = Jwk,
  DeriveKeyBytesInput = DeriveKeyBytesParams,
  DeriveKeyBytesOutput = Uint8Array,
  WrapKeyInput = WrapKeyParams,
  UnwrapKeyInput = UnwrapKeyParams
> extends
  DsaApi<GenerateKeyInput, GenerateKeyOutput, GetPublicKeyInput, DigestInput, SignInput, VerifyInput>,
  Cipher<EncryptInput, DecryptInput>,
  AsymmetricKeyConverter<BytesToPublicKeyInput, PublicKeyToBytesInput>,
  KeyConverter<BytesToPrivateKeyInput, PrivateKeyToBytesInput>,
  KeyDeriver<DeriveKeyInput, DeriveKeyOutput>,
  KeyBytesDeriver<DeriveKeyBytesInput, DeriveKeyBytesOutput>,
  KeyWrapper<WrapKeyInput, UnwrapKeyInput> {}