

import { CredoError } from "../../../error/CredoError.mjs";
import "../../../error/index.mjs";
import { JsonTransformer } from "../../../utils/JsonTransformer.mjs";
import "../../../utils/index.mjs";
import { isJsonObject } from "../../../types.mjs";
import { JwtPayload } from "../../../crypto/jose/jwt/JwtPayload.mjs";
import "../../../crypto/jose/jwt/index.mjs";
import { W3cCredential } from "../models/credential/W3cCredential.mjs";
import { w3cDate } from "../util.mjs";
import { isObject } from "class-validator";

//#region src/modules/vc/jwt-vc/credentialTransformer.ts
function getJwtPayloadFromCredential(credential) {
	const vc = JsonTransformer.toJSON(credential);
	const payloadOptions = { additionalClaims: { vc } };
	const issuanceDate = Date.parse(credential.issuanceDate);
	if (Number.isNaN(issuanceDate)) throw new CredoError("JWT VCs must have a valid issuance date");
	payloadOptions.nbf = Math.floor(issuanceDate / 1e3);
	delete vc.issuanceDate;
	if (credential.expirationDate) {
		const expirationDate = Date.parse(credential.expirationDate);
		if (!Number.isNaN(expirationDate)) {
			payloadOptions.exp = Math.floor(expirationDate / 1e3);
			delete vc.expirationDate;
		}
	}
	payloadOptions.iss = credential.issuerId;
	if (typeof vc.issuer === "string") delete vc.issuer;
	else if (typeof vc.issuer === "object") {
		delete vc.issuer.id;
		if (Object.keys(vc.issuer).length === 0) delete vc.issuer;
	}
	if (credential.id) {
		payloadOptions.jti = credential.id;
		delete vc.id;
	}
	if (Array.isArray(credential.credentialSubject) && credential.credentialSubject.length !== 1) throw new CredoError("JWT VCs must have exactly one credential subject");
	const [credentialSubjectId] = credential.credentialSubjectIds;
	if (credentialSubjectId) {
		payloadOptions.sub = credentialSubjectId;
		if (Array.isArray(vc.credentialSubject)) delete vc.credentialSubject[0].id;
		else delete vc.credentialSubject?.id;
	}
	return new JwtPayload(payloadOptions);
}
function getCredentialFromJwtPayload(jwtPayload) {
	if (!("vc" in jwtPayload.additionalClaims) || !isJsonObject(jwtPayload.additionalClaims.vc)) throw new CredoError("JWT does not contain a valid 'vc' claim");
	const jwtVc = jwtPayload.additionalClaims.vc;
	if (!jwtPayload.nbf || !jwtPayload.iss) throw new CredoError("JWT does not contain valid 'nbf' and 'iss' claims");
	if (Array.isArray(jwtVc.credentialSubject) && jwtVc.credentialSubject.length !== 1) throw new CredoError("JWT VCs must have exactly one credential subject");
	if (Array.isArray(jwtVc.credentialSubject) && !isObject(jwtVc.credentialSubject[0])) throw new CredoError("JWT VCs must have a credential subject of type object");
	const credentialSubject = Array.isArray(jwtVc.credentialSubject) ? jwtVc.credentialSubject[0] : jwtVc.credentialSubject;
	if (!isJsonObject(credentialSubject)) throw new CredoError("JWT VC does not have a valid credential subject");
	const subjectWithId = jwtPayload.sub ? {
		...credentialSubject,
		id: jwtPayload.sub
	} : credentialSubject;
	if (jwtVc.id && jwtPayload.jti !== jwtVc.id) throw new CredoError("JWT jti and vc.id do not match");
	if (typeof jwtVc.issuer === "string" && jwtPayload.iss !== jwtVc.issuer || isJsonObject(jwtVc.issuer) && jwtVc.issuer.id && jwtPayload.iss !== jwtVc.issuer.id) throw new CredoError("JWT iss and vc.issuer(.id) do not match");
	if (jwtVc.issuanceDate) {
		if (typeof jwtVc.issuanceDate !== "string") throw new CredoError("JWT vc.issuanceDate must be a string");
		const issuanceDate = Date.parse(jwtVc.issuanceDate) / 1e3;
		if (jwtPayload.nbf !== issuanceDate) throw new CredoError("JWT nbf and vc.issuanceDate do not match");
	}
	if (jwtVc.expirationDate) {
		if (typeof jwtVc.expirationDate !== "string") throw new CredoError("JWT vc.expirationDate must be a string");
		if (Date.parse(jwtVc.expirationDate) / 1e3 !== jwtPayload.exp) throw new CredoError("JWT exp and vc.expirationDate do not match");
	}
	if (isJsonObject(jwtVc.credentialSubject) && jwtVc.credentialSubject.id && jwtPayload.sub !== jwtVc.credentialSubject.id || Array.isArray(jwtVc.credentialSubject) && isJsonObject(jwtVc.credentialSubject[0]) && jwtVc.credentialSubject[0].id && jwtPayload.sub !== jwtVc.credentialSubject[0].id) throw new CredoError("JWT sub and vc.credentialSubject.id do not match");
	const dataModelVc = {
		...jwtVc,
		issuanceDate: w3cDate(jwtPayload.nbf * 1e3),
		expirationDate: jwtPayload.exp ? w3cDate(jwtPayload.exp * 1e3) : void 0,
		issuer: typeof jwtVc.issuer === "object" ? {
			...jwtVc.issuer,
			id: jwtPayload.iss
		} : jwtPayload.iss,
		id: jwtPayload.jti,
		credentialSubject: Array.isArray(jwtVc.credentialSubject) ? [subjectWithId] : subjectWithId
	};
	return JsonTransformer.fromJSON(dataModelVc, W3cCredential);
}

//#endregion
export { getCredentialFromJwtPayload, getJwtPayloadFromCredential };
//# sourceMappingURL=credentialTransformer.mjs.map