/**
 * NodeRemove — removes a node by tombstoning observed dots.
 */
import Op from "./Op.js";
import { OP_SCOPE_BOTH } from "./OpScope.js";
import { assertNonEmptyString, assertNoReservedBytes, assertArray } from "./validate.js";
import ReceiptBuilder from "../../services/ReceiptBuilder.js";
import DiffCalculator from "../../services/DiffCalculator.js";
export default class NodeRemove extends Op {
    receiptName = 'NodeTombstone';
    node;
    observedDots;
    constructor(node, observedDots) {
        super('NodeRemove', OP_SCOPE_BOTH);
        assertNonEmptyString(node, 'NodeRemove', 'node');
        assertNoReservedBytes(node, 'NodeRemove', 'node');
        assertArray(observedDots, 'NodeRemove', 'observedDots');
        for (let i = 0; i < observedDots.length; i += 1) {
            assertNonEmptyString(observedDots[i], 'NodeRemove', `observedDots[${i}]`);
        }
        this.node = node;
        this.observedDots = Object.freeze([...observedDots]);
        Object.freeze(this);
    }
    validate() { }
    mutate(state) {
        const dots = new Set(this.observedDots);
        state.nodeAlive.remove(dots);
    }
    outcome(state) {
        return ReceiptBuilder.nodeRemoveOutcome(state.nodeAlive, {
            node: this.node,
            observedDots: this.observedDots,
        });
    }
    snapshot(state) {
        return { aliveBeforeNodes: DiffCalculator.aliveElementsForDots(state.nodeAlive, new Set(this.observedDots)) };
    }
    accumulate(diff, state, before) {
        DiffCalculator.collectNodeRemovals(diff, state, before.aliveBeforeNodes);
    }
}
