import GitWarpBraidHologramMember from "./GitWarpBraidHologramMember.js";
import WarpError from "../errors/WarpError.js";
/** Replay-bearing hologram for materializing a settled braid weave. */
export default class GitWarpBraidHologram {
    settlementId;
    lawId;
    projectionDigest;
    proofRef;
    members;
    constructor(fields) {
        const checkedFields = requireFields(fields);
        this.settlementId = requireNonEmptyString(checkedFields.settlementId, 'settlementId');
        this.lawId = requireNonEmptyString(checkedFields.lawId, 'lawId');
        this.projectionDigest = requireNonEmptyString(checkedFields.projectionDigest, 'projectionDigest');
        this.proofRef = requireNonEmptyString(checkedFields.proofRef, 'proofRef');
        this.members = freezeMembers(checkedFields.members);
        Object.freeze(this);
    }
    /** Deterministically materializes the shared braid projection. */
    materializeFrom(basis) {
        let materialized = this.members[0]?.payload.replay(basis);
        if (materialized === undefined) {
            throw new WarpError('braid hologram requires materializable members', 'E_VALIDATION');
        }
        for (const member of this.members.slice(1)) {
            materialized = materialized.join(member.payload.replay(basis));
        }
        return materialized;
    }
}
function requireFields(value) {
    if (value === null || value === undefined) {
        throw new WarpError('GitWarpBraidHologram fields must be provided', 'E_VALIDATION');
    }
    return value;
}
function freezeMembers(values) {
    if (!Array.isArray(values) || values.length < 2) {
        throw new WarpError('braid hologram requires at least two members', 'E_VALIDATION');
    }
    const seen = new Set();
    const members = [];
    for (const value of values) {
        const member = requireMember(value);
        if (seen.has(member.strandId)) {
            throw new WarpError('braid hologram member strandId values must be unique', 'E_VALIDATION');
        }
        seen.add(member.strandId);
        members.push(member);
    }
    return Object.freeze(members.sort(compareMembers));
}
function requireMember(value) {
    if (!(value instanceof GitWarpBraidHologramMember)) {
        throw new WarpError('members must be GitWarpBraidHologramMember values', 'E_VALIDATION');
    }
    return value;
}
function compareMembers(left, right) {
    if (left.strandId < right.strandId) {
        return -1;
    }
    if (left.strandId > right.strandId) {
        return 1;
    }
    return 0;
}
function requireNonEmptyString(value, name) {
    if (typeof value !== 'string' || value.length === 0) {
        throw new WarpError(`${name} must be a non-empty string`, 'E_VALIDATION');
    }
    return value;
}
