import EdgeId from "./EdgeId.js";
import EdgeTypeId from "./EdgeTypeId.js";
import NodeId from "./NodeId.js";
import WarpError from "../errors/WarpError.js";
const LEGACY_EDGE_ID_PREFIX = 'legacy-edge';
/** Runtime-backed graph substrate edge record. */
export default class EdgeRecord {
    id;
    from;
    to;
    typeId;
    constructor(fields) {
        const checkedFields = requireFields(fields);
        this.id = requireEdgeId(checkedFields.id);
        this.from = requireNodeId(checkedFields.from, 'from');
        this.to = requireNodeId(checkedFields.to, 'to');
        this.typeId = requireEdgeTypeId(checkedFields.typeId);
        Object.freeze(this);
    }
    /** Builds a transitional edge record from legacy edge key fields. */
    static fromLegacyEdge(fields) {
        return new EdgeRecord({
            id: new EdgeId(legacyEdgeIdValue(fields)),
            from: new NodeId(fields.from),
            to: new NodeId(fields.to),
            typeId: new EdgeTypeId(fields.label),
        });
    }
    /** Compares edge records by graph identity, endpoints, and type. */
    equals(other) {
        return this.id.equals(other.id)
            && this.from.equals(other.from)
            && this.to.equals(other.to)
            && this.typeId.equals(other.typeId);
    }
}
/** Returns the deterministic transitional edge id for legacy edge fields. */
function legacyEdgeIdValue(fields) {
    return [
        LEGACY_EDGE_ID_PREFIX,
        segment(fields.from),
        segment(fields.to),
        segment(fields.label),
    ].join(':');
}
/** Length-prefixes a legacy edge id segment. */
function segment(value) {
    return `${value.length}:${value}`;
}
/** Validates the edge-record constructor envelope. */
function requireFields(fields) {
    if (fields === null || fields === undefined) {
        throw new WarpError('EdgeRecord fields must be provided', 'E_VALIDATION');
    }
    return fields;
}
/** Requires a runtime-backed edge id. */
function requireEdgeId(value) {
    if (!(value instanceof EdgeId)) {
        throw new WarpError('EdgeRecord id must be an EdgeId', 'E_VALIDATION');
    }
    return value;
}
/** Requires a runtime-backed node id for an edge endpoint. */
function requireNodeId(value, endpointName) {
    if (!(value instanceof NodeId)) {
        throw new WarpError(`EdgeRecord ${endpointName} must be a NodeId`, 'E_VALIDATION');
    }
    return value;
}
/** Requires a runtime-backed edge type id. */
function requireEdgeTypeId(value) {
    if (!(value instanceof EdgeTypeId)) {
        throw new WarpError('EdgeRecord typeId must be an EdgeTypeId', 'E_VALIDATION');
    }
    return value;
}
