import WarpError from "../../errors/WarpError.js";
import { ProvenanceIndex } from "../provenance/ProvenanceIndex.js";
function requireNonNegativeInteger(value, field) {
    if (!Number.isInteger(value) || value < 0) {
        throw new WarpError(`${field} must be a non-negative integer`, 'E_MATERIALIZE_PATCH_SUMMARY', { context: { field, value } });
    }
    return value;
}
export class MaterializePatchSummary {
    patchCount;
    maxObservedLamport;
    provenance;
    constructor(fields) {
        this.patchCount = requireNonNegativeInteger(fields.patchCount, 'patchCount');
        this.maxObservedLamport = requireNonNegativeInteger(fields.maxObservedLamport, 'maxObservedLamport');
        this.provenance = fields.provenance;
        Object.freeze(this);
    }
    static empty(provenanceBase) {
        return new MaterializePatchSummary({
            patchCount: 0,
            maxObservedLamport: 0,
            provenance: provenanceBase ? provenanceBase.clone() : new ProvenanceIndex(),
        });
    }
}
export class MaterializePatchSummaryAccumulator {
    #patchCount = 0;
    #maxObservedLamport = 0;
    #provenance;
    constructor(provenanceBase) {
        this.#provenance = provenanceBase ? provenanceBase.clone() : new ProvenanceIndex();
    }
    record(entry) {
        this.#patchCount += 1;
        if (Number.isInteger(entry.patch.lamport)) {
            this.#maxObservedLamport = Math.max(this.#maxObservedLamport, entry.patch.lamport);
        }
        this.#provenance.addPatch(entry.sha, entry.patch.reads, entry.patch.writes);
    }
    toSummary() {
        return new MaterializePatchSummary({
            patchCount: this.#patchCount,
            maxObservedLamport: this.#maxObservedLamport,
            provenance: this.#provenance,
        });
    }
}
export function summarizeMaterializePatches(patches, provenanceBase) {
    const accumulator = new MaterializePatchSummaryAccumulator(provenanceBase);
    for (const entry of patches) {
        accumulator.record(entry);
    }
    return accumulator.toSummary();
}
