

import { AgentContext } from "../../agent/context/AgentContext.mjs";
import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorateMetadata.mjs";
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.mjs";
import "../../agent/index.mjs";
import { KeyManagementError } from "./error/KeyManagementError.mjs";
import { KeyManagementKeyNotFoundError } from "./error/KeyManagementKeyNotFoundError.mjs";
import { getJwkHumanDescription } from "./jwk/humanDescription.mjs";
import { createKeyTypeForSigningAlgorithm } from "./jwk/alg/signing.mjs";
import { zParseWithErrorHandling } from "../../utils/zod.mjs";
import "./jwk/index.mjs";
import { KeyManagementModuleConfig } from "./KeyManagementModuleConfig.mjs";
import { getKmsOperationHumanDescription } from "./options/KmsOperation.mjs";
import "./options/index.mjs";
import { zWithBackend } from "./options/backend.mjs";
import { zKmsCreateKeyForSignatureAlgorithmOptions, zKmsCreateKeyOptions } from "./options/KmsCreateKeyOptions.mjs";
import { zKmsEncryptOptions } from "./options/KmsEncryptOptions.mjs";
import { zKmsDecryptOptions } from "./options/KmsDecryptOptions.mjs";
import { zKmsDeleteKeyOptions } from "./options/KmsDeleteKeyOptions.mjs";
import { zKmsGetPublicKeyOptions } from "./options/KmsGetPublicKeyOptions.mjs";
import { zKmsImportKeyOptions } from "./options/KmsImportKeyOptions.mjs";
import { zKmsRandomBytesOptions } from "./options/KmsRandomBytesOptions.mjs";
import { zKmsSignOptions } from "./options/KmsSignOptions.mjs";
import { zKmsVerifyOptions } from "./options/KmsVerifyOptions.mjs";
import { injectable } from "tsyringe";

//#region src/modules/kms/KeyManagementApi.ts
var _ref, _ref2;
let KeyManagementApi = class KeyManagementApi$1 {
	constructor(keyManagementConfig, agentContext) {
		this.keyManagementConfig = keyManagementConfig;
		this.agentContext = agentContext;
	}
	/**
	* Whether an operation is supported.
	*
	* @returns a list of backends that support the operation. In case
	* no backends are supported it returns an empty array
	*/
	supportedBackendsForOperation(operation) {
		const supportedBackends = [];
		for (const kms of this.keyManagementConfig.backends) if (kms.isOperationSupported(this.agentContext, operation)) supportedBackends.push(kms.backend);
		return supportedBackends;
	}
	/**
	* Create a key.
	*/
	async createKey(options) {
		const { backend,...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsCreateKeyOptions), options, "Invalid options provided to createKey method");
		const key = await this.getKms(this.agentContext, backend, {
			operation: "createKey",
			type: options.type
		}).createKey(this.agentContext, kmsOptions);
		key.publicJwk.kid = key.keyId;
		this.agentContext.config.logger.debug(`Created key ${getJwkHumanDescription(key.publicJwk)} with key id '${key.keyId}'`);
		return key;
	}
	/**
	* Create a key.
	*/
	async createKeyForSignatureAlgorithm(options) {
		const { backend, algorithm,...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsCreateKeyForSignatureAlgorithmOptions), options, "Invalid options provided to createKeyForSignatureAlgorithm method");
		const type = createKeyTypeForSigningAlgorithm(algorithm);
		const key = await this.getKms(this.agentContext, backend, {
			operation: "createKey",
			type
		}).createKey(this.agentContext, {
			...kmsOptions,
			type
		});
		key.publicJwk.kid = key.keyId;
		return key;
	}
	/**
	* Sign using a key.
	*/
	async sign(options) {
		const { backend,...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsSignOptions), options, "Invalid options provided to sign method");
		const operation = {
			operation: "sign",
			algorithm: options.algorithm
		};
		return await (backend ? this.getKms(this.agentContext, backend, operation) : (await this.getKmsForOperationAndKeyId(this.agentContext, options.keyId, operation)).kms).sign(this.agentContext, kmsOptions);
	}
	/**
	* Verify using a key.
	*/
	async verify(options) {
		const { backend,...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsVerifyOptions), options, "Invalid options provided to verify method");
		const operation = {
			operation: "verify",
			algorithm: options.algorithm
		};
		return await (backend || typeof options.key !== "string" ? this.getKms(this.agentContext, backend, operation) : (await this.getKmsForOperationAndKeyId(this.agentContext, options.key, operation)).kms).verify(this.agentContext, kmsOptions);
	}
	/**
	* Encrypt.
	*/
	async encrypt(options) {
		const { backend,...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsEncryptOptions), options, "Invalid options provided to encrypt method");
		const operation = {
			operation: "encrypt",
			encryption: options.encryption,
			keyAgreement: options.key.keyAgreement
		};
		return await (backend || typeof options.key !== "string" ? this.getKms(this.agentContext, backend, operation) : (await this.getKmsForOperationAndKeyId(this.agentContext, options.key, operation)).kms).encrypt(this.agentContext, kmsOptions);
	}
	/**
	* Decrypt.
	*/
	async decrypt(options) {
		const { backend,...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsDecryptOptions), options, "Invalid options provided to decrypt method");
		const operation = {
			operation: "decrypt",
			decryption: options.decryption,
			keyAgreement: options.key.keyAgreement
		};
		return await (backend || typeof options.key !== "string" ? this.getKms(this.agentContext, backend, operation) : (await this.getKmsForOperationAndKeyId(this.agentContext, options.key, operation)).kms).decrypt(this.agentContext, kmsOptions);
	}
	/**
	* Import a key.
	*/
	async importKey(options) {
		const { backend,...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsImportKeyOptions), options, "Invalid options provided to importKey method");
		const operation = {
			operation: "importKey",
			privateJwk: options.privateJwk
		};
		const key = await this.getKms(this.agentContext, backend, operation).importKey(this.agentContext, kmsOptions);
		this.agentContext.config.logger.trace(`Imported key ${getJwkHumanDescription(key.publicJwk)} with key id '${key.keyId}'`);
		return key;
	}
	/**
	* Get a public key.
	*/
	async getPublicKey(options) {
		const { backend, keyId } = zParseWithErrorHandling(zWithBackend(zKmsGetPublicKeyOptions), options, "Invalid options provided to getPublicKey method");
		if (backend) {
			if (!await this.getKms(this.agentContext, backend).getPublicKey(this.agentContext, keyId)) throw new KeyManagementKeyNotFoundError(keyId, [backend]);
		}
		const { publicKey } = await this.getKmsForOperationAndKeyId(this.agentContext, options.keyId);
		return publicKey;
	}
	/**
	* Delete a key.
	*/
	async deleteKey(options) {
		const { backend,...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsDeleteKeyOptions), options, "Invalid options provided to deleteKey method");
		return await this.getKms(this.agentContext, backend, { operation: "deleteKey" }).deleteKey(this.agentContext, kmsOptions);
	}
	/**
	* Generate random bytes
	*/
	randomBytes(options) {
		const { backend,...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsRandomBytesOptions), options, "Invalid options provided to randomBytes method");
		return this.getKms(this.agentContext, backend, { operation: "randomBytes" }).randomBytes(this.agentContext, kmsOptions);
	}
	/**
	* Get the kms associated with a specific `keyId`.
	*
	* This uses a naive approach of fetching the key for each configured kms
	* until it finds the registered key.
	*
	* In the future this approach might be optimized based on:
	* - caching
	* - keeping a registry
	* - backend specific key prefixes
	*/
	async getKmsForOperationAndKeyId(agentContext, keyId, operation) {
		for (const kms of this.keyManagementConfig.backends) {
			if (!(operation ? kms.isOperationSupported(agentContext, operation) : true)) continue;
			const publicKey = await kms.getPublicKey(this.agentContext, keyId);
			if (publicKey) return {
				publicKey,
				kms
			};
		}
		if (operation) throw new KeyManagementKeyNotFoundError(keyId, this.keyManagementConfig.backends.map((b) => b.backend), `The key may exist in one of the key management services in which case the key management service does not support the ${getKmsOperationHumanDescription(operation)}`);
		throw new KeyManagementKeyNotFoundError(keyId, this.keyManagementConfig.backends.map((b) => b.backend));
	}
	/**
	* Get the kms backend for a specific operation.
	*
	* If a backend is provided, it will be checked if the backend supports
	* the operation. Otherwise the first backend that supports the operation
	* will be used.
	*/
	getKms(agentContext, backend, operation) {
		if (backend) {
			const kms = this.keyManagementConfig.backends.find((kms$1) => kms$1.backend === backend);
			if (!kms) throw new KeyManagementError(`No key management service is configured for backend '${backend}'. Available backends are ${this.keyManagementConfig.backends.map((kms$1) => `'${kms$1.backend}'`).join(", ")}`);
			if (!(operation ? kms.isOperationSupported(agentContext, operation) : true) && operation) throw new KeyManagementError(`Key management service backend '${backend}' does not support ${getKmsOperationHumanDescription(operation)}`);
			return kms;
		}
		for (const kms of this.keyManagementConfig.backends) if (operation ? kms.isOperationSupported(agentContext, operation) : true) return kms;
		if (operation) throw new KeyManagementError(`No key management service backend found that supports ${getKmsOperationHumanDescription(operation)}`);
		throw new KeyManagementError("No key management service backend found.");
	}
};
KeyManagementApi = __decorate([injectable(), __decorateMetadata("design:paramtypes", [typeof (_ref = typeof KeyManagementModuleConfig !== "undefined" && KeyManagementModuleConfig) === "function" ? _ref : Object, typeof (_ref2 = typeof AgentContext !== "undefined" && AgentContext) === "function" ? _ref2 : Object])], KeyManagementApi);

//#endregion
export { KeyManagementApi };
//# sourceMappingURL=KeyManagementApi.mjs.map