

const require_CredoError = require('../../../../error/CredoError.js');
require('../../../../error/index.js');
const require_JsonEncoder = require('../../../../utils/JsonEncoder.js');
const require_JsonTransformer = require('../../../../utils/JsonTransformer.js');
require('../../../../utils/index.js');
const require_PublicJwk = require('../../../kms/jwk/PublicJwk.js');
require('../../../kms/index.js');
const require_parse = require('../../domain/parse.js');
const require_keyDidMapping = require('../../domain/key-type/keyDidMapping.js');
const require_DidDocumentService = require('../../domain/service/DidDocumentService.js');
const require_DidDocumentBuilder = require('../../domain/DidDocumentBuilder.js');
require('../../domain/index.js');

//#region src/modules/dids/methods/peer/peerDidNumAlgo2.ts
var DidPeerPurpose = /* @__PURE__ */ function(DidPeerPurpose$1) {
	DidPeerPurpose$1["Assertion"] = "A";
	DidPeerPurpose$1["Encryption"] = "E";
	DidPeerPurpose$1["Verification"] = "V";
	DidPeerPurpose$1["CapabilityInvocation"] = "I";
	DidPeerPurpose$1["CapabilityDelegation"] = "D";
	DidPeerPurpose$1["Service"] = "S";
	return DidPeerPurpose$1;
}(DidPeerPurpose || {});
function isDidPeerKeyPurpose(purpose) {
	return purpose !== DidPeerPurpose.Service && Object.values(DidPeerPurpose).includes(purpose);
}
const didPeerAbbreviations = {
	type: "t",
	DIDCommMessaging: "dm",
	serviceEndpoint: "s",
	routingKeys: "r",
	accept: "a"
};
const didPeerExpansions = {
	t: "type",
	dm: "DIDCommMessaging",
	s: "serviceEndpoint",
	r: "routingKeys",
	a: "accept"
};
function didToNumAlgo2DidDocument(did) {
	const entries = require_parse.parseDid(did).id.substring(2).split(".");
	const didDocument = new require_DidDocumentBuilder.DidDocumentBuilder(did);
	let serviceIndex = 0;
	let keyIndex = 1;
	for (const entry of entries) {
		const entryContent = entry.substring(1);
		const purpose = entry[0];
		if (purpose === DidPeerPurpose.Service) {
			let services = require_JsonEncoder.JsonEncoder.fromBase64(entryContent);
			services = Array.isArray(services) ? services : [services];
			for (let service of services) {
				service = expandServiceAbbreviations(service);
				service.id = `${did}#${service.type.toLowerCase()}-${serviceIndex++}`;
				didDocument.addService(require_JsonTransformer.JsonTransformer.fromJSON(service, require_DidDocumentService.DidDocumentService));
			}
		} else {
			const verificationMethods = require_keyDidMapping.getVerificationMethodsForPublicJwk(require_PublicJwk.PublicJwk.fromFingerprint(entryContent), did);
			for (const verificationMethod of verificationMethods) {
				verificationMethod.id = `${did}#key-${keyIndex++}`;
				addVerificationMethodToDidDocument(didDocument, verificationMethod, purpose);
			}
		}
	}
	return didDocument.build();
}
function didDocumentToNumAlgo2Did(didDocument) {
	const purposeMapping = {
		[DidPeerPurpose.Assertion]: didDocument.assertionMethod,
		[DidPeerPurpose.Encryption]: didDocument.keyAgreement,
		[DidPeerPurpose.Verification]: didDocument.authentication,
		[DidPeerPurpose.CapabilityInvocation]: didDocument.capabilityInvocation,
		[DidPeerPurpose.CapabilityDelegation]: didDocument.capabilityDelegation
	};
	let did = "did:peer:2";
	const keys = [];
	for (const [purpose, entries] of Object.entries(purposeMapping)) {
		if (entries === void 0) continue;
		const dereferenced = entries.map((entry) => typeof entry === "string" ? didDocument.dereferenceVerificationMethod(entry) : entry);
		for (const entry of dereferenced) {
			const encoded = `.${purpose}${require_keyDidMapping.getPublicJwkFromVerificationMethod(entry).fingerprint}`;
			keys.push({
				id: entry.id,
				encoded
			});
		}
	}
	const prefix = "key-";
	if (!keys.every((key) => key.id.split("#")[1]?.startsWith(prefix))) throw new require_CredoError.CredoError("Ids for keys within DID Document for did:peer:2 creation must follow the pattern `#key-n`");
	did += keys.sort((a, b) => {
		const aFragment = a.id.split("#")[1];
		const bFragment = b.id.split("#")[1];
		return Number(aFragment.replace(prefix, "")) - Number(bFragment.replace(prefix, ""));
	}).map((key) => key.encoded).join("");
	if (didDocument.service && didDocument.service.length > 0) {
		const abbreviatedServices = didDocument.service.map((service) => {
			const serviceJson = require_JsonTransformer.JsonTransformer.toJSON(service);
			serviceJson.id = void 0;
			return abbreviateServiceJson(serviceJson);
		});
		for (const abbreviatedService of abbreviatedServices) {
			const encodedService = require_JsonEncoder.JsonEncoder.toBase64URL(abbreviatedService);
			did += `.${DidPeerPurpose.Service}${encodedService}`;
		}
	}
	return did;
}
function expandServiceAbbreviations(service) {
	const expand = (abbreviated) => didPeerExpansions[abbreviated] ?? abbreviated;
	const expandJson = (json) => {
		if (!json) return json;
		if (typeof json === "number") return json;
		if (typeof json === "string") return expand(json);
		if (Array.isArray(json)) return json.map(expandJson);
		if (typeof json === "object") return Object.entries(json).reduce((jsonBody, [key, value]) => ({
			...jsonBody,
			[expand(key)]: expandJson(value)
		}), {});
	};
	const fullService = expandJson(service);
	if ("t" in service && service.t === "dm" && typeof service.serviceEndpoint === "string") return {
		...fullService,
		type: "DIDComm"
	};
	return fullService;
}
function abbreviateServiceJson(service) {
	const abbreviate = (expanded) => didPeerAbbreviations[expanded] ?? expanded;
	return Object.entries(service).reduce((serviceBody, [key, value]) => ({
		...serviceBody,
		[abbreviate(key)]: abbreviate(value)
	}), {});
}
function addVerificationMethodToDidDocument(didDocument, verificationMethod, purpose) {
	const purposeMapping = {
		[DidPeerPurpose.Assertion]: didDocument.addAssertionMethod.bind(didDocument),
		[DidPeerPurpose.Encryption]: didDocument.addKeyAgreement.bind(didDocument),
		[DidPeerPurpose.Verification]: didDocument.addAuthentication.bind(didDocument),
		[DidPeerPurpose.CapabilityInvocation]: didDocument.addCapabilityInvocation.bind(didDocument),
		[DidPeerPurpose.CapabilityDelegation]: didDocument.addCapabilityDelegation.bind(didDocument)
	};
	if (isDidPeerKeyPurpose(purpose)) {
		const addVerificationMethod = purposeMapping[purpose];
		addVerificationMethod(verificationMethod);
	} else throw new require_CredoError.CredoError(`Unsupported peer did purpose '${purpose}'`);
}

//#endregion
exports.didDocumentToNumAlgo2Did = didDocumentToNumAlgo2Did;
exports.didToNumAlgo2DidDocument = didToNumAlgo2DidDocument;