// engine/event-schema-validator/drift-detector.ts — Schema drift detection (SPEC-031)
import { asStringArray, asPropertiesMap } from './helpers.js';
/**
 * Compare an implemented schema object against a versioned EventContract.
 * Returns null when no breaking drift is found (additive drift is acceptable).
 */
export function detectDrift(contract, implementedSchema) {
    const schema = contract.versions[contract.currentVersion];
    if (!schema) {
        return null;
    }
    const contractProps = asPropertiesMap(schema.jsonSchema.properties);
    const contractRequired = asStringArray(schema.jsonSchema.required);
    const implProps = asPropertiesMap(implementedSchema.properties);
    const mismatches = [];
    for (const field of contractRequired) {
        const contractProp = contractProps[field];
        const implProp = implProps[field];
        if (!implProp) {
            mismatches.push({
                field,
                expectedType: contractProp?.type ?? 'unknown',
                actualType: 'missing',
                required: true,
            });
            continue;
        }
        const expectedType = contractProp?.type ?? 'unknown';
        const actualType = implProp.type ?? 'unknown';
        if (expectedType !== actualType) {
            mismatches.push({
                field,
                expectedType,
                actualType,
                required: true,
            });
        }
    }
    const optionalMismatches = [];
    for (const field of Object.keys(contractProps)) {
        if (contractRequired.includes(field)) {
            continue;
        }
        const contractProp = contractProps[field];
        const implProp = implProps[field];
        if (implProp) {
            const expectedType = contractProp?.type ?? 'unknown';
            const actualType = implProp.type ?? 'unknown';
            if (expectedType !== actualType) {
                optionalMismatches.push({
                    field,
                    expectedType,
                    actualType,
                    required: false,
                });
            }
        }
    }
    if (mismatches.length === 0 && optionalMismatches.length > 0) {
        return {
            contractName: contract.name,
            expectedVersion: contract.currentVersion,
            mismatches: optionalMismatches,
            severity: 'additive',
        };
    }
    if (mismatches.length === 0) {
        return null;
    }
    return {
        contractName: contract.name,
        expectedVersion: contract.currentVersion,
        mismatches: [...mismatches, ...optionalMismatches],
        severity: 'breaking',
    };
}
//# sourceMappingURL=drift-detector.js.map