import { ReceiptShard } from "../artifacts/ReceiptShard.js";
import WarpError from "../errors/WarpError.js";
import { DeliveryObservation } from "../types/DeliveryObservation.js";
import { TickReceipt } from "../types/TickReceipt.js";
/** Local git-warp facts that can be projected into the Continuum receipt family. */
export default class GitWarpReceiptSourceFacts {
    tickReceipt;
    deliveryObservations;
    receiptShard;
    /** Builds immutable projection inputs from local git-warp receipt carriers. */
    constructor(fields) {
        const checkedFields = requireFields(fields);
        this.tickReceipt = requireTickReceipt(checkedFields.tickReceipt);
        requireReceiptOutcomes(this.tickReceipt);
        this.deliveryObservations = optionalDeliveryObservations(checkedFields.deliveryObservations);
        this.receiptShard = optionalReceiptShard(checkedFields.receiptShard);
        Object.freeze(this);
    }
}
/** Validates the source-facts constructor envelope. */
function requireFields(value) {
    if (value === null || value === undefined) {
        throw new WarpError('GitWarpReceiptSourceFacts fields must be provided', 'E_VALIDATION');
    }
    return value;
}
/** Validates that the source fact is a concrete TickReceipt. */
function requireTickReceipt(value) {
    if (!(value instanceof TickReceipt)) {
        throw new WarpError('tickReceipt must be a TickReceipt', 'E_VALIDATION');
    }
    return value;
}
/** Receipt-family projection needs at least one local operation outcome. */
function requireReceiptOutcomes(receipt) {
    if (receipt.ops.length === 0) {
        throw new WarpError('tickReceipt must contain at least one operation outcome', 'E_VALIDATION');
    }
}
/** Validates optional delivery observations without accepting null as omission. */
function optionalDeliveryObservations(values) {
    if (values === undefined) {
        return Object.freeze([]);
    }
    if (!Array.isArray(values)) {
        throw new WarpError('deliveryObservations must be an array', 'E_VALIDATION');
    }
    return freezeDeliveryObservations(values);
}
/** Freezes and validates delivery observations. */
function freezeDeliveryObservations(values) {
    const observations = [];
    for (const value of values) {
        observations.push(requireDeliveryObservation(value));
    }
    return Object.freeze(observations);
}
/** Validates a delivery-observation carrier. */
function requireDeliveryObservation(value) {
    if (!(value instanceof DeliveryObservation)) {
        throw new WarpError('deliveryObservations[] must be a DeliveryObservation', 'E_VALIDATION');
    }
    return value;
}
/** Validates an optional receipt-shard carrier. */
function optionalReceiptShard(value) {
    if (value === undefined) {
        return undefined;
    }
    if (!(value instanceof ReceiptShard)) {
        throw new WarpError('receiptShard must be a ReceiptShard', 'E_VALIDATION');
    }
    return value;
}
