import type {
  KeyIdentifier,
  KmsSignParams,
  KmsDigestParams,
  KmsVerifyParams,
  KmsGetKeyUriParams,
  KmsGenerateKeyParams,
  KmsGetPublicKeyParams,
} from '@web5/crypto';

import type { DsaApi } from './crypto-api.js';
import type { KmsCipherParams } from './params-kms.js';
// import type { Web5PlatformAgent } from '../../../types/agent.js';

export interface KeyManagerParams {
  CipherInput?: unknown;
  GenerateKeyInput?: unknown;
  GenerateKeyOutput?: unknown;
  GetPublicKeyInput?: unknown;
  SignInput?: unknown;
  VerifyInput?: unknown;
}

export interface DefaultKeyManagerParams {
  CipherInput: KmsCipherParams;
  GenerateKeyInput: KmsGenerateKeyParams;
  GenerateKeyOutput: KeyIdentifier;
  GetPublicKeyInput: KmsGetPublicKeyParams;
  SignInput: KmsSignParams;
  VerifyInput: KmsVerifyParams;
}

/**
 * The `KeyManager` interface integrates key generation and signing capabilities.
 *
 * Concrete implementations of this interface are intended to be used as a Key Management System
 * (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 can be
 * a local software based KMS, a cloud service, or a hardware device.
 *
 * 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 an signing operations.
 * - May be extended to support other cryptographic operations.
 * - Implementations of the `CryptoApi` 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.).
 *
 * @example
 * ```ts
 * // Example of using the KeyManager interface with default types
 * class DefaultKeyManager implements KeyManager {} // Uses default types
 *
 * // Example of using the KeyManager interface with custom types
 * class CustomKeyManager implements KeyManager<{
 *   GenerateKeyInput: CustomGenerateKeyParams, // Custom type
 *   KmsGetPublicKeyParams: CustomGetPublicKeyParams, // Custom type
 *   KmsSignParams: CustomSignParams, // Custom type
 *   // Omitting KmsVerifyParams to use the default
 * }> {
 *   // Implementation here
 * }
 * ```
 *
 * @typeParam T - The type of the key manager parameters.
 */
export interface KeyManager<T extends KeyManagerParams = DefaultKeyManagerParams>
  extends DsaApi<T['GenerateKeyInput'], T['GenerateKeyOutput'], T['GetPublicKeyInput'], KmsDigestParams, T['SignInput'], T['VerifyInput']> {

  /**
   *
   * @param params - The parameters for getting the key URI.
   * @param params.key - The key to get the URI for.
   * @returns The key URI.
   */
  getKeyUri(params: KmsGetKeyUriParams): Promise<KeyIdentifier>;
}