

const require_CredoError = require('../../error/CredoError.js');
require('../../error/index.js');
require('../../agent/index.js');
const require_TypedArrayEncoder = require('../../utils/TypedArrayEncoder.js');
require('../../utils/index.js');
const require_PublicJwk = require('../kms/jwk/PublicJwk.js');
const require_KeyManagementApi = require('../kms/KeyManagementApi.js');
require('../kms/index.js');
const require_parse = require('../dids/domain/parse.js');
const require_keyDidMapping = require('../dids/domain/key-type/keyDidMapping.js');
const require_DidResolverService = require('../dids/services/DidResolverService.js');
const require_DidsApi = require('../dids/DidsApi.js');
require('../dids/index.js');

//#region src/modules/sd-jwt-vc/utils.ts
async function resolveSigningPublicJwkFromDidUrl(agentContext, didUrl) {
	const { publicJwk } = await agentContext.dependencyManager.resolve(require_DidsApi.DidsApi).resolveVerificationMethodFromCreatedDidRecord(didUrl);
	return publicJwk;
}
async function resolveDidUrl(agentContext, didUrl) {
	const didDocument = await agentContext.dependencyManager.resolve(require_DidResolverService.DidResolverService).resolveDidDocument(agentContext, didUrl);
	return {
		verificationMethod: didDocument.dereferenceKey(didUrl, ["assertionMethod"]),
		didDocument
	};
}
async function extractKeyFromHolderBinding(agentContext, holder, forSigning = false) {
	if (holder.method === "did") {
		if (!require_parse.parseDid(holder.didUrl).fragment) throw new require_CredoError.CredoError(`didUrl '${holder.didUrl}' does not contain a '#'. Unable to derive key from did document`);
		let publicJwk;
		if (forSigning) publicJwk = await resolveSigningPublicJwkFromDidUrl(agentContext, holder.didUrl);
		else {
			const { verificationMethod } = await resolveDidUrl(agentContext, holder.didUrl);
			publicJwk = require_keyDidMapping.getPublicJwkFromVerificationMethod(verificationMethod);
		}
		const supportedSignatureAlgorithms = publicJwk.supportedSignatureAlgorithms;
		if (supportedSignatureAlgorithms.length === 0) throw new require_CredoError.CredoError(`No supported JWA signature algorithms found for key ${publicJwk.jwkTypehumanDescription}`);
		return {
			alg: supportedSignatureAlgorithms[0],
			publicJwk,
			cnf: { kid: holder.didUrl }
		};
	}
	if (holder.method === "jwk") {
		const publicJwk = holder.jwk;
		const alg = publicJwk.supportedSignatureAlgorithms[0];
		if (forSigning && !publicJwk.hasKeyId) publicJwk.keyId = publicJwk.legacyKeyId;
		return {
			alg,
			publicJwk,
			cnf: { jwk: publicJwk.toJson() }
		};
	}
	throw new require_CredoError.CredoError("Unsupported credential holder binding. Only 'did' and 'jwk' are supported at the moment.");
}
/**
* @todo validate the JWT header (alg)
*/
function getSdJwtSigner(agentContext, key) {
	const kms = agentContext.resolve(require_KeyManagementApi.KeyManagementApi);
	return async (input) => {
		const result = await kms.sign({
			keyId: key.keyId,
			data: require_TypedArrayEncoder.TypedArrayEncoder.fromString(input),
			algorithm: key.signatureAlgorithm
		});
		return require_TypedArrayEncoder.TypedArrayEncoder.toBase64URL(result.signature);
	};
}
/**
* @todo validate the JWT header (alg)
*/
function getSdJwtVerifier(agentContext, key) {
	const kms = agentContext.resolve(require_KeyManagementApi.KeyManagementApi);
	return async (message, signatureBase64Url) => {
		return (await kms.verify({
			signature: require_TypedArrayEncoder.TypedArrayEncoder.fromBase64(signatureBase64Url),
			key: { publicJwk: key.toJson() },
			data: require_TypedArrayEncoder.TypedArrayEncoder.fromString(message),
			algorithm: key.signatureAlgorithm
		})).verified;
	};
}
function parseHolderBindingFromCredential(payload) {
	if (!payload) throw new require_CredoError.CredoError("Unable to extract payload from SD-JWT VC");
	if (!payload.cnf) return null;
	const cnf = payload.cnf;
	if (cnf.jwk) return {
		method: "jwk",
		jwk: require_PublicJwk.PublicJwk.fromUnknown(cnf.jwk)
	};
	if (cnf.kid) {
		if (!cnf.kid.startsWith("did:") || !cnf.kid.includes("#")) throw new require_CredoError.CredoError("Invalid holder kid for did. Only absolute KIDs for cnf are supported");
		return {
			method: "did",
			didUrl: cnf.kid
		};
	}
	throw new require_CredoError.CredoError("Unsupported credential holder binding. Only 'did' and 'jwk' are supported at the moment.");
}

//#endregion
exports.extractKeyFromHolderBinding = extractKeyFromHolderBinding;
exports.getSdJwtSigner = getSdJwtSigner;
exports.getSdJwtVerifier = getSdJwtVerifier;
exports.parseHolderBindingFromCredential = parseHolderBindingFromCredential;
exports.resolveDidUrl = resolveDidUrl;
exports.resolveSigningPublicJwkFromDidUrl = resolveSigningPublicJwkFromDidUrl;