/**
 * KMS/HSM client for key management
 */

import {
  KMSClient as AWSKMSClient,
  EncryptCommand,
  DecryptCommand,
  SignCommand,
  VerifyCommand,
} from '@aws-sdk/client-kms';

export interface KMSConfig {
  provider: 'aws' | 'gcp' | 'azure' | 'hsm';
  keyId: string;
  region?: string;
}

export class KMSClient {
  protected kmsClient: AWSKMSClient;
  protected keyId: string;

  constructor(protected config: KMSConfig) {
    this.keyId = config.keyId;
    this.kmsClient = new AWSKMSClient({
      region: config.region || 'us-east-1',
    });
  }

  async encrypt(plaintext: Buffer): Promise<Buffer> {
    const command = new EncryptCommand({
      KeyId: this.keyId,
      Plaintext: plaintext,
    });

    const response = await this.kmsClient.send(command);
    if (!response.CiphertextBlob) {
      throw new Error('Encryption failed: no ciphertext returned');
    }

    return Buffer.from(response.CiphertextBlob);
  }

  async decrypt(ciphertext: Buffer): Promise<Buffer> {
    const command = new DecryptCommand({
      CiphertextBlob: ciphertext,
    });

    const response = await this.kmsClient.send(command);
    if (!response.Plaintext) {
      throw new Error('Decryption failed: no plaintext returned');
    }

    return Buffer.from(response.Plaintext);
  }

  async sign(data: Buffer): Promise<Buffer> {
    const command = new SignCommand({
      KeyId: this.keyId,
      Message: data,
      MessageType: 'RAW',
      SigningAlgorithm: 'RSASSA_PKCS1_V1_5_SHA_256',
    });

    const response = await this.kmsClient.send(command);
    if (!response.Signature) {
      throw new Error('Signing failed: no signature returned');
    }

    return Buffer.from(response.Signature);
  }

  async verify(data: Buffer, signature: Buffer): Promise<boolean> {
    const command = new VerifyCommand({
      KeyId: this.keyId,
      Message: data,
      Signature: signature,
      MessageType: 'RAW',
      SigningAlgorithm: 'RSASSA_PKCS1_V1_5_SHA_256',
    });

    const response = await this.kmsClient.send(command);
    return response.SignatureValid ?? false;
  }
}

