/**
 * Schema version detection and compatibility validation for WARP messages.
 */
import { EDGE_PROP_PREFIX } from "../KeyCodec.js";
import SchemaUnsupportedError from "../../errors/SchemaUnsupportedError.js";
import EdgePropSet from "../../types/ops/EdgePropSet.js";
import PropSet from "../../types/ops/PropSet.js";
import { getCodec, TRAILER_KEYS } from "./MessageCodecInternal.js";
// ── Constants ───────────────────────────────────────────────────────
/** Patch schema v2 — classic node-only patches. */
export const CLASSIC_PATCH_SCHEMA_VERSION = 2;
/** Patch schema v3 — edge-property-aware patches. */
export const EDGE_PROPERTY_PATCH_SCHEMA_VERSION = 3;
export const PATCH_SCHEMA_CLASSIC = CLASSIC_PATCH_SCHEMA_VERSION;
export const PATCH_SCHEMA_EDGE_PROPERTIES = EDGE_PROPERTY_PATCH_SCHEMA_VERSION;
// ── Schema version detection ────────────────────────────────────────
function isEdgePropOp(op) {
    if (op instanceof EdgePropSet) {
        return true;
    }
    return op instanceof PropSet && op.node.startsWith(EDGE_PROP_PREFIX);
}
/** Detects the schema version required for a set of ops. */
export function detectSchemaVersion(ops) {
    if (!Array.isArray(ops)) {
        return CLASSIC_PATCH_SCHEMA_VERSION;
    }
    for (const op of ops) {
        if (op === null || op === undefined || typeof op !== 'object') {
            continue;
        }
        if (isEdgePropOp(op)) {
            return EDGE_PROPERTY_PATCH_SCHEMA_VERSION;
        }
    }
    return CLASSIC_PATCH_SCHEMA_VERSION;
}
// ── Schema compatibility ────────────────────────────────────────────
/** Asserts ops are compatible with a max supported schema version. */
export function assertOpsCompatible(ops, maxSchema) {
    if (maxSchema >= EDGE_PROPERTY_PATCH_SCHEMA_VERSION) {
        return;
    }
    if (!Array.isArray(ops)) {
        return;
    }
    for (const op of ops) {
        if (op === null || op === undefined || typeof op !== 'object') {
            continue;
        }
        if (isEdgePropOp(op)) {
            throw new SchemaUnsupportedError('Upgrade to >=7.3.0 (WEIGHTED) to sync edge properties.', {
                context: { requiredSchema: EDGE_PROPERTY_PATCH_SCHEMA_VERSION, maxSupportedSchema: maxSchema },
            });
        }
    }
}
const VALID_KINDS = new Set(['patch', 'checkpoint', 'anchor', 'audit']);
/** Detects the WARP message kind from a raw commit message. */
export function detectMessageKind(message) {
    if (typeof message !== 'string') {
        return null;
    }
    try {
        const decoded = getCodec().decode(message);
        const kind = decoded.trailers[TRAILER_KEYS['kind'] ?? 'eg-kind'];
        if (typeof kind === 'string' && VALID_KINDS.has(kind)) {
            return kind;
        }
        return null;
    }
    catch {
        return null;
    }
}
