import GraphContentAttachmentSetOp from "../graph/GraphContentAttachmentSetOp.js";
import GraphEdgeRecordSetOp from "../graph/GraphEdgeRecordSetOp.js";
import GraphEdgePropertySetOp from "../graph/GraphEdgePropertySetOp.js";
import GraphNodeRecordSetOp from "../graph/GraphNodeRecordSetOp.js";
import GraphNodePropertySetOp from "../graph/GraphNodePropertySetOp.js";
import GraphOpAlgebra from "../graph/GraphOpAlgebra.js";
import WarpError from "../errors/WarpError.js";
import ContentAttachmentProjection from "./ContentAttachmentProjection.js";
import EdgePropertyProjection from "./EdgePropertyProjection.js";
import NodePropertyProjection from "./NodePropertyProjection.js";
import WarpState from "./state/WarpState.js";
/** Projects materialized graph state into the explicit graph-operation algebra. */
export default class GraphOpAlgebraProjection {
    /** Returns graph operations ordered as nodes, edges, content, node props, then edge props. */
    static fromState(state) {
        const checkedState = requireWarpState(state);
        const operations = [];
        appendNodeRecordOps(operations, checkedState);
        appendEdgeRecordOps(operations, checkedState);
        appendContentAttachmentOps(operations, checkedState);
        appendNodePropertyOps(operations, checkedState);
        appendEdgePropertyOps(operations, checkedState);
        return new GraphOpAlgebra({ operations });
    }
}
/** Requires a runtime-backed WarpState projection source. */
function requireWarpState(state) {
    if (!(state instanceof WarpState)) {
        throw new WarpError('GraphOpAlgebraProjection source must be a WarpState', 'E_VALIDATION');
    }
    return state;
}
/** Appends node record operations in state iteration order. */
function appendNodeRecordOps(operations, state) {
    for (const record of state.nodeRecords()) {
        operations.push(new GraphNodeRecordSetOp({ record }));
    }
}
/** Appends edge record operations in state iteration order. */
function appendEdgeRecordOps(operations, state) {
    for (const record of state.edgeRecords()) {
        operations.push(new GraphEdgeRecordSetOp({ record }));
    }
}
/** Appends typed content attachment operations. */
function appendContentAttachmentOps(operations, state) {
    for (const record of ContentAttachmentProjection.fromState(state)) {
        operations.push(new GraphContentAttachmentSetOp({ record }));
    }
}
/** Appends typed node property operations, excluding content compatibility aliases. */
function appendNodePropertyOps(operations, state) {
    for (const record of NodePropertyProjection.fromState(state)) {
        if (!record.key.isContentCompatibilityKey()) {
            operations.push(new GraphNodePropertySetOp({ record }));
        }
    }
}
/** Appends typed edge property operations, excluding content compatibility aliases. */
function appendEdgePropertyOps(operations, state) {
    for (const record of EdgePropertyProjection.fromState(state)) {
        if (!record.key.isContentCompatibilityKey()) {
            operations.push(new GraphEdgePropertySetOp({ record }));
        }
    }
}
