import { Cid } from '../utils/cid.js';
import { Encoder } from '../utils/encoder.js';
import { Encryption } from '../utils/encryption.js';
import { GeneralJwsBuilder } from '../jose/jws/general/builder.js';
import { Jws } from '../utils/jws.js';
import { removeUndefinedProperties } from '@enbox/common';
import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
/** Creates the RecordsWrite `encryption` property if encryption input is given. */
export async function createEncryptionProperty(encryptionInput) {
    if (encryptionInput === undefined) {
        return undefined;
    }
    return Encryption.buildEncryptionProperty(encryptionInput);
}
/**
 * Creates the `attestation` property of a RecordsWrite message if given signature inputs; returns `undefined` otherwise.
 */
export async function createAttestation(descriptorCid, signers) {
    if (signers === undefined || signers.length === 0) {
        return undefined;
    }
    const attestationPayload = { descriptorCid };
    const attestationPayloadBytes = Encoder.objectToBytes(attestationPayload);
    const builder = await GeneralJwsBuilder.create(attestationPayloadBytes, signers);
    return builder.getJws();
}
/**
 * Creates the `signature` property in the `authorization` of a `RecordsWrite` message.
 */
export async function createSignerSignature(input) {
    const { recordId, contextId, descriptorCid, attestation, encryption, signer, delegatedGrantId, permissionGrantId, protocolRole } = input;
    const attestationCid = attestation ? await Cid.computeCid(attestation) : undefined;
    const encryptionCid = encryption ? await Cid.computeCid(encryption) : undefined;
    const signaturePayload = {
        recordId,
        descriptorCid,
        contextId,
        attestationCid,
        encryptionCid,
        delegatedGrantId,
        permissionGrantId,
        protocolRole
    };
    removeUndefinedProperties(signaturePayload);
    const signaturePayloadBytes = Encoder.objectToBytes(signaturePayload);
    const builder = await GeneralJwsBuilder.create(signaturePayloadBytes, [signer]);
    const signature = builder.getJws();
    return signature;
}
/**
 * Validates the structural integrity of the `attestation` property.
 * NOTE: Cryptographic verification of attestation signatures is performed in `authenticate()`.
 */
export async function validateAttestationIntegrity(message) {
    if (message.attestation === undefined) {
        return;
    }
    // TODO: support multiple attesters (https://github.com/enboxorg/enbox/issues/223)
    if (message.attestation.signatures.length !== 1) {
        throw new DwnError(DwnErrorCode.RecordsWriteAttestationIntegrityMoreThanOneSignature, `Currently implementation only supports 1 attester, but got ${message.attestation.signatures.length}`);
    }
    const payloadJson = Jws.decodePlainObjectPayload(message.attestation);
    const { descriptorCid } = payloadJson;
    // `descriptorCid` validation - ensure that the provided descriptorCid matches the CID of the actual message
    const expectedDescriptorCid = await Cid.computeCid(message.descriptor);
    if (descriptorCid !== expectedDescriptorCid) {
        throw new DwnError(DwnErrorCode.RecordsWriteAttestationIntegrityDescriptorCidMismatch, `descriptorCid ${descriptorCid} does not match expected descriptorCid ${expectedDescriptorCid}`);
    }
    // check to ensure that no other unexpected properties exist in payload.
    const propertyCount = Object.keys(payloadJson).length;
    if (propertyCount > 1) {
        throw new DwnError(DwnErrorCode.RecordsWriteAttestationIntegrityInvalidPayloadProperty, `Only 'descriptorCid' is allowed in attestation payload, but got ${propertyCount} properties.`);
    }
}
//# sourceMappingURL=records-write-signing.js.map