"""Shared Pydantic validators for API schemas."""


MAX_FOLDER_SIZE_MB = 10
MAX_FOLDER_SIZE_BYTES = MAX_FOLDER_SIZE_MB * 1024 * 1024


def validate_mount_path(v: str | None) -> str | None:
    """Validate that a mount path is absolute (starts with /).

    Args:
        v: Mount path string or None.

    Returns:
        The validated path, or None if input was None.

    Raises:
        ValueError: If path is not absolute.
    """
    if v is None:
        return v
    if not v.startswith("/"):
        raise ValueError("Mount path must be absolute (start with /)")
    return v


def validate_files(v: dict | None, max_size_bytes: int = MAX_FOLDER_SIZE_BYTES) -> dict | None:
    """Validate file dict for path traversal and size limits.

    Args:
        v: Dict of {path: content} or None.
        max_size_bytes: Maximum total size in bytes.

    Returns:
        The validated dict, or None if input was None.

    Raises:
        ValueError: If path traversal detected or size limit exceeded.
    """
    if v is None:
        return v

    total_size = 0
    for path, content in v.items():
        # Check for path traversal
        if ".." in path or path.startswith("/"):
            raise ValueError(f"Invalid file path: {path}")
        total_size += len(content.encode("utf-8"))

    if total_size > max_size_bytes:
        raise ValueError(f"Total folder size exceeds {max_size_bytes // (1024 * 1024)}MB limit")

    return v


def validate_env_vars(v: dict | None) -> dict | None:
    """Validate that environment variables is a JSON object.

    Args:
        v: Dict of env vars or None.

    Returns:
        The validated dict, or None if input was None.

    Raises:
        ValueError: If not a dict.
    """
    if v is None:
        return v
    if not isinstance(v, dict):
        raise ValueError("environment_variables must be a JSON object")
    return v


def validate_volumes(v: list | None) -> list | None:
    """Validate volume mounts list.

    Args:
        v: List of volume dicts or None.

    Returns:
        The validated list, or None if input was None.

    Raises:
        ValueError: If not a list or missing required fields.
    """
    if v is None:
        return v
    if not isinstance(v, list):
        raise ValueError("volumes must be a JSON array")
    for i, vol in enumerate(v):
        if not isinstance(vol, dict):
            raise ValueError(f"Volume at index {i} must be an object")
        if "source" not in vol:
            raise ValueError(f"Volume at index {i} must have 'source' field")
        if "target" not in vol:
            raise ValueError(f"Volume at index {i} must have 'target' field")
    return v
