# Copyright Visual Collaboration Technologies Inc. All Rights Reserved.
# See LICENSE for details.
"""Configuration error types for structured error reporting."""


class ConfigError(Exception):
    """Base for all config errors."""


class DecodeError(ConfigError):
    """A string value could not be decoded to the target type.

    Attributes:
        field_name: Name of the field that failed decoding.
        raw_value: The raw string that could not be decoded.
    """

    def __init__(self, message: str, *, field_name: str = "", raw_value: str = "") -> None:
        super().__init__(message)
        self.field_name = field_name
        self.raw_value = raw_value


class MissingFieldError(ConfigError):
    """A required field has no value from any source.

    Attributes:
        field_name: Name of the missing field.
        env_name: Environment variable name that was checked.
    """

    def __init__(self, message: str, *, field_name: str = "", env_name: str = "") -> None:
        super().__init__(message)
        self.field_name = field_name
        self.env_name = env_name


class ValidationError(ConfigError):
    """A decoded value failed validation.

    Attributes:
        field_name: Name of the field that failed validation.
        value: The decoded value that did not pass validation.
    """

    def __init__(self, message: str, *, field_name: str = "", value: object = None) -> None:
        super().__init__(message)
        self.field_name = field_name
        self.value = value


class ConfigErrors(ConfigError):
    """Multiple config errors collected during schema loading.

    Attributes:
        errors: List of individual config errors.
    """

    def __init__(self, errors: list[ConfigError]) -> None:
        self.errors = errors
        super().__init__(self._format())

    def _format(self) -> str:
        lines = [f"{len(self.errors)} configuration error(s):"]
        for i, err in enumerate(self.errors, 1):
            lines.append(f"  {i}. [{type(err).__name__}] {err}")
        return "\n".join(lines)


__all__ = [
    "ConfigError",
    "DecodeError",
    "MissingFieldError",
    "ValidationError",
    "ConfigErrors",
]
