"""
Exception hierarchy for SPARQLMojo ORM.
"""


class SPARQLMojoError(Exception):
    """Base exception for all SPARQLMojo errors."""

    pass


class ConfigurationError(SPARQLMojoError):
    """Raised when configuration is invalid or missing."""

    pass


class ValidationError(SPARQLMojoError):
    """Raised when data validation fails."""

    pass


class ModelError(SPARQLMojoError):
    """Base exception for model-related errors."""

    pass


class FieldError(ModelError):
    """Raised when field operation fails."""

    pass


class UnknownFieldError(FieldError):
    """Raised when accessing undefined field on model."""

    def __init__(self, model_class: type, field_name: str):
        self.model_class = model_class
        self.field_name = field_name
        # Use _rdf_fields instead of _fields to match our model implementation
        rdf_fields = getattr(model_class, "_rdf_fields", {})
        available_fields = list(rdf_fields.keys())
        super().__init__(
            f"Field '{field_name}' is not defined on model "
            f"'{model_class.__name__}'. "
            f"Available fields: {', '.join(available_fields)}"
        )


class RequiredFieldError(FieldError):
    """Raised when required field is missing."""

    pass


class SessionError(SPARQLMojoError):
    """Base exception for session-related errors."""

    pass


class ConnectionError(SessionError):
    """Raised when connection to SPARQL endpoint fails."""

    pass


class QueryError(SessionError):
    """Raised when SPARQL query execution fails."""

    def __init__(self, message: str, query: str | None = None):
        self.query = query
        if query:
            super().__init__(f"{message}\n\nQuery:\n{query}")
        else:
            super().__init__(message)


class SPARQLSyntaxError(QueryError):
    """Raised when generated SPARQL has syntax errors."""

    pass


class IRIError(ValidationError):
    """Raised when IRI validation fails."""

    def __init__(self, iri: str, reason: str):
        self.iri = iri
        super().__init__(f"Invalid IRI '{iri}': {reason}")
