/**
 * ConflictOpAnchor — runtime-backed anchor for malformed legacy ops
 * that conflict analysis still needs to diagnose.
 *
 * @module domain/services/strand/ConflictOpAnchor
 */
import { OP_STRATEGIES } from "../JoinReducer.js";
import { normalizeHashableEffectValue } from "./conflictHashableEffectValue.js";
export function receiptNameForRawType(opType) {
    return OP_STRATEGIES.get(opType)?.receiptName ?? null;
}
function readNode(op) {
    return 'node' in op && typeof op.node === 'string' ? op.node : null;
}
function readFrom(op) {
    return 'from' in op && typeof op.from === 'string' ? op.from : null;
}
function readTo(op) {
    return 'to' in op && typeof op.to === 'string' ? op.to : null;
}
function readLabel(op) {
    return 'label' in op && typeof op.label === 'string' ? op.label : null;
}
function readKey(op) {
    return 'key' in op && typeof op.key === 'string' ? op.key : null;
}
function readDot(op) {
    return 'dot' in op && op.dot !== undefined ? op.dot : null;
}
function readObservedDots(op) {
    if (!('observedDots' in op) || op.observedDots === undefined) {
        return null;
    }
    return op.observedDots;
}
function readValue(op) {
    return 'value' in op ? normalizeHashableEffectValue(op.value) : null;
}
function readOid(op) {
    return 'oid' in op && typeof op.oid === 'string' ? op.oid : null;
}
/**
 * Runtime-backed anchor for known but structurally incomplete legacy
 * op records. It preserves diagnostic behavior without reintroducing
 * erased shape aliases.
 */
export default class ConflictOpAnchor {
    type;
    receiptName;
    node;
    from;
    to;
    label;
    key;
    dot;
    observedDots;
    value;
    oid;
    constructor(fields) {
        this.type = fields.type;
        this.receiptName = fields.receiptName;
        this.node = fields.node;
        this.from = fields.from;
        this.to = fields.to;
        this.label = fields.label;
        this.key = fields.key;
        this.dot = fields.dot;
        this.observedDots = fields.observedDots;
        this.value = fields.value;
        this.oid = fields.oid;
        Object.freeze(this);
    }
    static from(rawOp) {
        const receiptName = receiptNameForRawType(rawOp.type);
        if (receiptName === null) {
            return null;
        }
        return new ConflictOpAnchor({
            type: rawOp.type,
            receiptName,
            node: readNode(rawOp),
            from: readFrom(rawOp),
            to: readTo(rawOp),
            label: readLabel(rawOp),
            key: readKey(rawOp),
            dot: readDot(rawOp),
            observedDots: readObservedDots(rawOp),
            value: readValue(rawOp),
            oid: readOid(rawOp),
        });
    }
}
