"""Input validation utilities for SDKRouter SDK.

Catches invalid inputs before they hit the API — saves time and money.
"""


def validate_text_input(text: str, field_name: str = "input") -> None:
    """Validate that text is suitable for LLM/embedding API calls.

    Raises:
        ValueError: If text is empty, binary, or contains NUL bytes.
    """
    if not isinstance(text, str):
        raise ValueError(f"{field_name} must be a string, got {type(text).__name__}")

    if not text.strip():
        raise ValueError(f"{field_name} is empty")

    # NUL bytes — PostgreSQL and most APIs can't handle these
    if "\x00" in text:
        raise ValueError(f"{field_name} contains NUL (\\x00) bytes — likely binary data")

    # High ratio of non-printable chars = binary content
    sample = text[:500]
    non_printable = sum(1 for c in sample if ord(c) < 32 and c not in "\n\r\t")
    if len(sample) > 20 and non_printable > len(sample) * 0.1:
        raise ValueError(
            f"{field_name} appears to contain binary data "
            f"({non_printable}/{len(sample)} non-printable chars in first 500 bytes)"
        )


def validate_embedding_input(input_data: str | list[str]) -> list[str]:
    """Validate and normalize embedding input.

    Args:
        input_data: Single string or list of strings to embed.

    Returns:
        List of validated strings.

    Raises:
        ValueError: If input is invalid.
    """
    if isinstance(input_data, str):
        texts = [input_data]
    elif isinstance(input_data, list):
        texts = input_data
    else:
        raise ValueError(f"input must be str or list[str], got {type(input_data).__name__}")

    if not texts:
        raise ValueError("input is empty — nothing to embed")

    for i, text in enumerate(texts):
        validate_text_input(text, field_name=f"input[{i}]")

    return texts


def validate_messages(messages: list) -> None:
    """Validate chat messages contain text content, not binary.

    Args:
        messages: List of message dicts with 'content' field.

    Raises:
        ValueError: If any message content is binary.
    """
    for i, msg in enumerate(messages):
        if not isinstance(msg, dict):
            continue
        content = msg.get("content")
        if isinstance(content, str) and content:
            validate_text_input(content, field_name=f"messages[{i}].content")
