/**
 * Shared validation utilities for conflict domain types.
 *
 * These helpers validate runtime invariants on values whose TypeScript
 * types are already known (the calling constructors accept typed fields).
 * They live at the boundary between TS typing and runtime truth: the
 * type system promises "string, number, boolean", but the runtime value
 * may still be empty, negative, or out of range.
 *
 * Every helper accepts the declared TS input type. Cycle 0025B3 removed
 * the wide-net untyped signatures that used to live here; validators
 * that genuinely cross an untyped boundary live inside type-guard
 * predicates (`isFoo(value): value is Foo`) in the modules that own the
 * boundary.
 *
 * @module domain/types/conflict/validation
 */
import WarpError from "../../errors/WarpError.js";
/**
 * Validates that a string value is non-empty.
 */
export function requireNonEmptyString(value, name, context) {
    if (typeof value !== 'string' || value.length === 0) {
        throw new WarpError(`${context}: ${name} must be a non-empty string`, 'E_VALIDATION');
    }
    return value;
}
/**
 * Validates that a numeric value is a non-negative integer.
 */
export function requireNonNegativeInt(value, name, context) {
    if (!Number.isInteger(value) || value < 0) {
        throw new WarpError(`${context}: ${name} must be a non-negative integer`, 'E_VALIDATION');
    }
    return value;
}
/**
 * Validates that a value is a boolean.
 */
export function requireBoolean(value, name, context) {
    if (typeof value !== 'boolean') {
        throw new WarpError(`${context}: ${name} must be a boolean`, 'E_VALIDATION');
    }
    return value;
}
/**
 * Validates that a string value belongs to a fixed allowed set.
 */
export function requireEnum(value, allowed, { name, context }) {
    if (!allowed.has(value)) {
        throw new WarpError(`${context}: ${name} must be one of ${[...allowed].join(', ')}`, 'E_VALIDATION');
    }
    return value;
}
/**
 * Validates an optional string — must be non-empty when present.
 */
export function optionalString(value, name, context) {
    if (value === undefined || value === null) {
        return undefined;
    }
    return requireNonEmptyString(value, name, context);
}
/**
 * Validates an optional enum — must be in the allowed set when present.
 */
export function optionalEnum(value, allowed, label) {
    if (value === undefined || value === null) {
        return undefined;
    }
    return requireEnum(value, allowed, label);
}
/**
 * Deep-freezes an optional diagnostic data payload. Returns undefined
 * when absent.
 */
export function freezeOptionalDiagnosticData(value) {
    if (value === undefined || value === null) {
        return undefined;
    }
    const copy = {};
    for (const key of Object.keys(value)) {
        const v = value[key];
        if (v !== undefined) {
            copy[key] = v;
        }
    }
    return Object.freeze(copy);
}
/**
 * Freezes an array of strings, returning an empty frozen array when absent.
 */
export function freezeStringArray(value) {
    if (value === null || value === undefined) {
        return Object.freeze([]);
    }
    return Object.freeze([...value]);
}
/**
 * Lexicographic string comparison for sorting.
 */
export function compareStrings(a, b) {
    if (a === b) {
        return 0;
    }
    return a < b ? -1 : 1;
}
