

const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.js');
const require_CredoError = require('../../../error/CredoError.js');
require('../../../error/index.js');
const require_Hasher = require('../../../crypto/hashes/Hasher.js');
const require_ClaimFormat = require('../../vc/models/ClaimFormat.js');
require('../../../crypto/index.js');
const require_W3cCredentialRecord = require('../../vc/repository/W3cCredentialRecord.js');
require('../../vc/index.js');
const require_MdocRecord = require('../../mdoc/repository/MdocRecord.js');
const require_SdJwtVcRecord = require('../../sd-jwt-vc/repository/SdJwtVcRecord.js');
const require_MdocDeviceResponse = require('../../mdoc/MdocDeviceResponse.js');
require('../../mdoc/index.js');
require('../../sd-jwt-vc/index.js');
const require_DifPresentationExchangeError = require('../DifPresentationExchangeError.js');
const require_transform = require('./transform.js');
let __sd_jwt_decode = require("@sd-jwt/decode");
let __animo_id_pex = require("@animo-id/pex");
let __animo_id_pex_dist_main_lib_evaluation_core_index_js = require("@animo-id/pex/dist/main/lib/evaluation/core/index.js");
let __astronautlabs_jsonpath = require("@astronautlabs/jsonpath");
let __sphereon_pex_models = require("@sphereon/pex-models");

//#region src/modules/dif-presentation-exchange/utils/credentialSelection.ts
async function getCredentialsForRequest(pex, presentationDefinition, credentialRecords) {
	const encodedCredentials = credentialRecords.map(require_transform.getSphereonOriginalVerifiableCredential);
	const selectResultsRaw = pex.selectFrom(presentationDefinition, encodedCredentials);
	const selectResults = {
		...selectResultsRaw,
		matches: selectResultsRaw.matches ?? [],
		verifiableCredential: selectResultsRaw.verifiableCredential?.map((selectedEncoded, index) => {
			const credentialRecordIndex = selectResultsRaw.vcIndexes?.[index];
			if (credentialRecordIndex === void 0 || credentialRecordIndex === -1) throw new require_DifPresentationExchangeError.DifPresentationExchangeError("Unable to find credential in credential records.");
			const credentialRecord = credentialRecords[credentialRecordIndex];
			if (credentialRecord instanceof require_SdJwtVcRecord.SdJwtVcRecord) {
				const { jwt, disclosures } = (0, __sd_jwt_decode.decodeSdJwtSync)(selectedEncoded, require_Hasher.Hasher.hash);
				const prettyClaims = (0, __sd_jwt_decode.getClaimsSync)(jwt.payload, disclosures, require_Hasher.Hasher.hash);
				return {
					claimFormat: require_ClaimFormat.ClaimFormat.SdJwtDc,
					credentialRecord,
					disclosedPayload: prettyClaims
				};
			}
			if (credentialRecord instanceof require_MdocRecord.MdocRecord) return {
				claimFormat: require_ClaimFormat.ClaimFormat.MsoMdoc,
				credentialRecord,
				disclosedPayload: {}
			};
			if (credentialRecord instanceof require_W3cCredentialRecord.W3cCredentialRecord) return {
				claimFormat: credentialRecord.firstCredential.claimFormat,
				credentialRecord
			};
			throw new require_CredoError.CredoError("Unrecognized credential record type");
		}) ?? []
	};
	const presentationSubmission = {
		requirements: [],
		areRequirementsSatisfied: false,
		name: presentationDefinition.name,
		purpose: presentationDefinition.purpose
	};
	if (!presentationDefinition.submission_requirements || presentationDefinition.submission_requirements.length === 0) presentationSubmission.requirements = getSubmissionRequirementsForAllInputDescriptors(presentationDefinition.input_descriptors, selectResults);
	else presentationSubmission.requirements = getSubmissionRequirements(presentationDefinition, selectResults);
	const allEntries = presentationSubmission.requirements.flatMap((requirement) => requirement.submissionEntry);
	const inputDescriptorsForMdocCredential = /* @__PURE__ */ new Map();
	for (const entry of allEntries) for (const verifiableCredential of entry.verifiableCredentials) {
		if (verifiableCredential.claimFormat !== require_ClaimFormat.ClaimFormat.MsoMdoc) continue;
		const set = inputDescriptorsForMdocCredential.get(verifiableCredential) ?? /* @__PURE__ */ new Set();
		set.add(entry.inputDescriptorId);
		inputDescriptorsForMdocCredential.set(verifiableCredential, set);
	}
	for (const [verifiableCredential, inputDescriptorIds] of inputDescriptorsForMdocCredential.entries()) {
		if (verifiableCredential.claimFormat !== require_ClaimFormat.ClaimFormat.MsoMdoc) continue;
		const inputDescriptorsForCredential = presentationDefinition.input_descriptors.filter(({ id }) => inputDescriptorIds.has(id));
		const mdoc = verifiableCredential.credentialRecord.firstCredential;
		verifiableCredential.disclosedPayload = require_MdocDeviceResponse.MdocDeviceResponse.limitDisclosureToInputDescriptor({
			inputDescriptor: {
				id: mdoc.docType,
				format: { mso_mdoc: { alg: [] } },
				constraints: {
					limit_disclosure: "required",
					fields: inputDescriptorsForCredential.flatMap((i) => i.constraints?.fields ?? [])
				}
			},
			mdoc
		});
	}
	if (presentationSubmission.requirements.length === 0) throw new require_DifPresentationExchangeError.DifPresentationExchangeError("Presentation Definition does not require any credentials. Optional credentials are not included in the presentation submission.");
	if (selectResults.areRequiredCredentialsPresent === __animo_id_pex.Status.ERROR) return presentationSubmission;
	return {
		...presentationSubmission,
		areRequirementsSatisfied: presentationSubmission.requirements.every((requirement) => requirement.isRequirementSatisfied)
	};
}
function getSubmissionRequirements(presentationDefinition, selectResults) {
	const submissionRequirements = [];
	const matches = selectResults.matches;
	if (!matches.every((match) => match.type === __animo_id_pex_dist_main_lib_evaluation_core_index_js.SubmissionRequirementMatchType.SubmissionRequirement && match.from)) throw new require_DifPresentationExchangeError.DifPresentationExchangeError(`Expected all matches to be of type '${__animo_id_pex_dist_main_lib_evaluation_core_index_js.SubmissionRequirementMatchType.SubmissionRequirement}' with 'from' key.`);
	presentationDefinition.submission_requirements?.forEach((submissionRequirement, submissionRequirementIndex) => {
		if (submissionRequirement.from_nested) throw new require_DifPresentationExchangeError.DifPresentationExchangeError("Presentation definition contains requirement using 'from_nested', which is not supported yet.");
		if (!submissionRequirement.from) throw new require_DifPresentationExchangeError.DifPresentationExchangeError("Missing 'from' in submission requirement match");
		const match = matches.find((match$1) => match$1.id === submissionRequirementIndex);
		if (!match) throw new Error(`Unable to find a match for submission requirement with index '${submissionRequirementIndex}'`);
		if (submissionRequirement.rule === __sphereon_pex_models.Rules.All) {
			const selectedSubmission = getSubmissionRequirementRuleAll(submissionRequirement, presentationDefinition, selectResults.verifiableCredential, match);
			submissionRequirements.push(selectedSubmission);
		} else {
			const selectedSubmission = getSubmissionRequirementRulePick(submissionRequirement, presentationDefinition, selectResults.verifiableCredential, match);
			submissionRequirements.push(selectedSubmission);
		}
	});
	return submissionRequirements.filter((requirement) => requirement.needsCount > 0);
}
function getSubmissionRequirementsForAllInputDescriptors(inputDescriptors, selectResults) {
	const submissionRequirements = [];
	const matches = selectResults.matches;
	if (!matches.every((match) => match.type === __animo_id_pex_dist_main_lib_evaluation_core_index_js.SubmissionRequirementMatchType.InputDescriptor)) throw new require_DifPresentationExchangeError.DifPresentationExchangeError(`Expected all matches to be of type '${__animo_id_pex_dist_main_lib_evaluation_core_index_js.SubmissionRequirementMatchType.InputDescriptor}' when.`);
	for (const inputDescriptor of inputDescriptors) {
		const submission = getSubmissionForInputDescriptor(inputDescriptor, selectResults.verifiableCredential, matches);
		submissionRequirements.push({
			rule: __sphereon_pex_models.Rules.Pick,
			needsCount: 1,
			submissionEntry: [submission],
			isRequirementSatisfied: submission.verifiableCredentials.length >= 1
		});
	}
	return submissionRequirements;
}
function getSubmissionRequirementRuleAll(submissionRequirement, presentationDefinition, verifiableCredentials, match) {
	if (!submissionRequirement.from) throw new require_DifPresentationExchangeError.DifPresentationExchangeError("Missing 'from' in submission requirement match.");
	const selectedSubmission = {
		rule: __sphereon_pex_models.Rules.All,
		needsCount: 0,
		name: submissionRequirement.name,
		purpose: submissionRequirement.purpose,
		submissionEntry: [],
		isRequirementSatisfied: false
	};
	for (const inputDescriptor of presentationDefinition.input_descriptors) {
		if (!inputDescriptor.group?.includes(match.from)) continue;
		const submission = getSubmissionForInputDescriptor(inputDescriptor, verifiableCredentials, match.input_descriptors);
		selectedSubmission.needsCount += 1;
		selectedSubmission.submissionEntry.push(submission);
	}
	return {
		...selectedSubmission,
		isRequirementSatisfied: selectedSubmission.submissionEntry.every((submission) => submission.verifiableCredentials.length >= 1)
	};
}
function getSubmissionRequirementRulePick(submissionRequirement, presentationDefinition, verifiableCredentials, match) {
	if (!submissionRequirement.from) throw new require_DifPresentationExchangeError.DifPresentationExchangeError("Missing 'from' in submission requirement match.");
	const selectedSubmission = {
		rule: __sphereon_pex_models.Rules.Pick,
		needsCount: submissionRequirement.count ?? submissionRequirement.min ?? 1,
		name: submissionRequirement.name,
		purpose: submissionRequirement.purpose,
		submissionEntry: [],
		isRequirementSatisfied: false
	};
	const satisfiedSubmissions = [];
	const unsatisfiedSubmissions = [];
	for (const inputDescriptor of presentationDefinition.input_descriptors) {
		if (!inputDescriptor.group?.includes(match.from)) continue;
		const submission = getSubmissionForInputDescriptor(inputDescriptor, verifiableCredentials, match.input_descriptors);
		if (submission.verifiableCredentials.length >= 1) satisfiedSubmissions.push(submission);
		else unsatisfiedSubmissions.push(submission);
	}
	return {
		...selectedSubmission,
		isRequirementSatisfied: satisfiedSubmissions.length >= selectedSubmission.needsCount,
		submissionEntry: satisfiedSubmissions.length >= selectedSubmission.needsCount ? satisfiedSubmissions : [...satisfiedSubmissions, ...unsatisfiedSubmissions]
	};
}
function getSubmissionForInputDescriptor(inputDescriptor, verifiableCredentials, matches) {
	const matchesForInputDescriptor = matches.filter((m) => m.id === inputDescriptor.id);
	const submissionEntry = {
		inputDescriptorId: inputDescriptor.id,
		name: inputDescriptor.name,
		purpose: inputDescriptor.purpose,
		verifiableCredentials: matchesForInputDescriptor.flatMap((matchForInputDescriptor) => extractCredentialsFromInputDescriptorMatch(matchForInputDescriptor, verifiableCredentials))
	};
	if (!matchesForInputDescriptor?.length) return submissionEntry;
	return submissionEntry;
}
function extractCredentialsFromInputDescriptorMatch(match, availableCredentials) {
	const verifiableCredentials = [];
	for (const vcPath of match.vc_path) {
		const [verifiableCredential] = __astronautlabs_jsonpath.JSONPath.query({ verifiableCredential: availableCredentials }, vcPath);
		verifiableCredentials.push(verifiableCredential);
	}
	return verifiableCredentials;
}

//#endregion
exports.getCredentialsForRequest = getCredentialsForRequest;