# AUTO-GENERATED FILE — DO NOT EDIT
# Generated by scripts/generate_constants.py
# Source: schema/assertion_types.json (single source of truth)

"""
Auto-generated CLM assertion validators.

These functions implement the cross-language assertion contracts
defined in schema/assertion_types.json, ensuring identical validation
behavior in both Python and TypeScript.
"""

import json
from typing import Any


def assert_result(actual: Any, expected: Any) -> bool:
    """Exact deep-equality match (assertion_types.json: result)."""
    if isinstance(expected, dict) and isinstance(actual, dict):
        return all(
            k in actual and assert_result(actual[k], v) for k, v in expected.items()
        )
    if isinstance(expected, list) and isinstance(actual, list):
        return len(expected) == len(actual) and all(
            assert_result(a, e) for a, e in zip(actual, expected, strict=False)
        )
    if isinstance(expected, int | float) and isinstance(actual, int | float):
        return abs(expected - actual) < 1e-6
    return expected == actual


def assert_result_contains(actual: Any, substring: str) -> bool:
    """Substring match, case-insensitive (assertion_types.json: result_contains)."""
    actual_str = json.dumps(actual) if not isinstance(actual, str) else actual
    return substring.lower() in actual_str.lower()


def assert_result_type(actual: Any, expected_type: str) -> bool:
    """Type check (assertion_types.json: result_type)."""
    type_map: dict[str, type | tuple[type, ...]] = {
        "object": dict,
        "string": str,
        "number": (int, float),
        "array": list,
        "boolean": bool,
    }
    expected_cls = type_map.get(expected_type)
    if expected_cls is None:
        return False
    return isinstance(actual, expected_cls)


def assert_schema(actual: Any, schema: dict) -> bool:
    """Structural validation (assertion_types.json: schema).

    Validates that actual matches the given schema structure:
    - type: expected type
    - required: list of required keys
    - properties: nested schemas for object properties
    - minLength/maxLength: for strings/arrays
    - min/max: for numbers
    - enum: list of allowed values
    - items: schema for array items
    """
    if not isinstance(schema, dict):
        return True

    # Type check
    if "type" in schema:
        if not assert_result_type(actual, schema["type"]):
            return False

    # Required keys
    if "required" in schema and isinstance(actual, dict):
        for key in schema["required"]:
            if key not in actual:
                return False

    # Properties
    if "properties" in schema and isinstance(actual, dict):
        for key, sub_schema in schema["properties"].items():
            if key in actual:
                if not assert_schema(actual[key], sub_schema):
                    return False

    # Length checks (strings/arrays)
    if "minLength" in schema and hasattr(actual, "__len__"):
        if len(actual) < schema["minLength"]:
            return False
    if "maxLength" in schema and hasattr(actual, "__len__"):
        if len(actual) > schema["maxLength"]:
            return False
    if "length" in schema and hasattr(actual, "__len__"):
        if len(actual) != schema["length"]:
            return False

    # Numeric range
    if "min" in schema and isinstance(actual, int | float):
        if actual < schema["min"]:
            return False
    if "max" in schema and isinstance(actual, int | float):
        if actual > schema["max"]:
            return False

    # Enum
    if "enum" in schema:
        if actual not in schema["enum"]:
            return False

    # Array items
    if "items" in schema and isinstance(actual, list):
        for item in actual:
            if not assert_schema(item, schema["items"]):
                return False

    return True


# Map assertion type names to validator functions
ASSERTION_VALIDATORS = {
    "result": assert_result,
    "result_contains": assert_result_contains,
    "result_type": assert_result_type,
    "schema": assert_schema,
}
