"""
Custom exception hierarchy for domain-specific errors.

All exceptions inherit from BaseApplicationError for centralized handling.
"""

from typing import Any


class BaseApplicationError(Exception):
    """Base exception for all application errors."""

    def __init__(self, message: str, details: dict[str, Any] | None = None):
        self.message = message
        self.details = details or {}
        super().__init__(self.message)


# Dataset Exceptions
class DatasetError(BaseApplicationError):
    """Base exception for dataset-related errors."""


class DatasetNotFoundError(DatasetError):
    """Raised when a dataset is not found."""


class DatasetUploadError(DatasetError):
    """Raised when dataset upload fails."""


class InvalidDatasetFormatError(DatasetError):
    """Raised when dataset format is not supported."""


class SchemaDetectionError(DatasetError):
    """Raised when schema detection fails."""


# Pipeline Exceptions
class PipelineError(BaseApplicationError):
    """Base exception for pipeline-related errors."""


class PipelineNotFoundError(PipelineError):
    """Raised when a pipeline is not found."""


class PipelineCompilationError(PipelineError):
    """Raised when pipeline compilation fails."""


class PipelineExecutionError(PipelineError):
    """Raised when pipeline execution fails."""


class InvalidIRError(PipelineError):
    """Raised when IR is malformed or invalid."""


class DAGValidationError(PipelineError):
    """Raised when DAG validation fails (cycles, invalid dependencies, etc.)."""


# Agent Exceptions
class AgentError(BaseApplicationError):
    """Base exception for agent-related errors."""


class PlannerError(AgentError):
    """Raised when Planner agent fails."""


class CompilerError(AgentError):
    """Raised when Compiler agent fails."""


class ExecutorError(AgentError):
    """Raised when Executor agent fails."""


class ValidatorError(AgentError):
    """Raised when Validator agent fails."""


class OptimizerError(AgentError):
    """Raised when Optimizer agent fails."""


# Transformation Exceptions
class TransformationError(BaseApplicationError):
    """Base exception for transformation-related errors."""


class InvalidTransformationError(TransformationError):
    """Raised when a transformation is not recognized."""


class TransformationExecutionError(TransformationError):
    """Raised when transformation execution fails."""


class InsufficientResourcesError(TransformationError):
    """Raised when system resources are insufficient."""


# Validation Exceptions
class ValidationError(BaseApplicationError):
    """Base exception for validation errors."""


class DataQualityError(ValidationError):
    """Raised when data quality checks fail."""


class SchemaValidationError(ValidationError):
    """Raised when schema validation fails."""


# Storage Exceptions
class StorageError(BaseApplicationError):
    """Base exception for storage-related errors."""


class FileNotFoundError(StorageError):
    """Raised when a file is not found in storage."""


class FileWriteError(StorageError):
    """Raised when file write operation fails."""


class DatabaseError(StorageError):
    """Raised when database operation fails."""


# API Exceptions
class APIError(BaseApplicationError):
    """Base exception for API-related errors."""


class AuthenticationError(APIError):
    """Raised when authentication fails."""


class AuthorizationError(APIError):
    """Raised when authorization fails."""


class RateLimitError(APIError):
    """Raised when rate limit is exceeded."""


class InvalidRequestError(APIError):
    """Raised when request is malformed."""
