/**
 * JSON Schema validation engine using ajv.
 * @epic T4454
 * @task T4458
 */
import { ExitCode } from '@cleocode/contracts';
import { default as AjvImport } from 'ajv';
import { default as addFormatsImport } from 'ajv-formats';
import { CleoError } from './errors.js';
import { readJson } from './store/json.js';
// Handle ESM/CJS interop for Ajv and ajv-formats
const ajvMod = AjvImport;
const Ajv = (typeof ajvMod.default === 'function' ? ajvMod.default : AjvImport);
const fmtMod = addFormatsImport;
const addFormats = (typeof fmtMod.default === 'function' ? fmtMod.default : addFormatsImport);
/** Singleton ajv instance. */
let ajvInstance = null;
function getAjv() {
    if (!ajvInstance) {
        ajvInstance = new Ajv({
            allErrors: true,
            strict: false,
            allowUnionTypes: true,
        });
        addFormats(ajvInstance);
    }
    return ajvInstance;
}
/** Compiled schema cache. */
const schemaCache = new Map();
/**
 * Validate data against a JSON Schema object.
 * Throws CleoError on validation failure.
 */
export function validateAgainstSchema(data, schema, schemaId) {
    const ajv = getAjv();
    const cacheKey = schemaId ?? JSON.stringify(schema);
    let validate = schemaCache.get(cacheKey);
    if (!validate) {
        validate = ajv.compile(schema);
        schemaCache.set(cacheKey, validate);
    }
    if (!validate(data)) {
        const errors = validate.errors
            ?.map((e) => `${e.instancePath || '/'}: ${e.message}`)
            .join('; ');
        throw new CleoError(ExitCode.VALIDATION_ERROR, `Schema validation failed: ${errors ?? 'unknown error'}`);
    }
}
/**
 * Load a JSON Schema file and validate data against it.
 */
export async function validateAgainstSchemaFile(data, schemaPath) {
    const schema = await readJson(schemaPath);
    if (!schema) {
        throw new CleoError(ExitCode.NOT_FOUND, `Schema file not found: ${schemaPath}`);
    }
    validateAgainstSchema(data, schema, schemaPath);
}
/**
 * Check if data is valid against a schema without throwing.
 * Returns an array of error messages (empty if valid).
 */
export function checkSchema(data, schema) {
    try {
        validateAgainstSchema(data, schema);
        return [];
    }
    catch (err) {
        if (err instanceof CleoError) {
            return [err.message];
        }
        return [String(err)];
    }
}
//# sourceMappingURL=json-schema-validator.js.map