# File: src/noveler/domain/exceptions/__init__.py
# Purpose: Aggregate and extend domain-level exception types for external import.
# Context: Provides specialised exceptions with repository strict-mode metadata.

"""ドメイン例外パッケージ."""

from noveler.domain.exceptions.base import (
    BusinessRuleViolationError,
    ConfigurationError,
    DomainException,
    DomainValidationError,
    EpisodeCompletionError,
    EpisodeNotFoundError,
    InsufficientDataError,
    InvalidOperationError,
    InvalidStatusError,
    InvalidVersionError,
    NoEpisodesFoundError,
    PathResolutionError,
    PlotNotFoundError,
    ProjectConfigNotFoundError,
    ProjectNotFoundError,
    QualityCheckError,
    QualityRecordError,
    QualityRecordNotFoundError,
    RecordTransactionError,
    RepositoryError,
    StateTransitionError,
    ValidationError,
)
from noveler.domain.exceptions.chapter_plot_exceptions import ChapterPlotNotFoundError
from noveler.domain.exceptions.viewpoint_exceptions import (
    ViewpointDataInvalidError,
    ViewpointError,
    ViewpointFileNotFoundError,
    ViewpointRepositoryError,
    ViewpointYAMLParseError,
)


class MissingProjectRootError(PathResolutionError):
    """Project root を特定できない場合の例外."""

    def __init__(self, hint: str | None = None) -> None:
        message = "Project root could not be determined"
        context: dict[str, str] | None = None
        if hint:
            message = f"{message}: {hint}"
            context = {"hint": hint}
        super().__init__(message, context)


class MissingConfigurationError(ConfigurationError):
    """必須設定が不足している場合の例外."""

    def __init__(self, config_name: str, message: str | None = None) -> None:
        detail_msg = message or f"Required configuration '{config_name}' is missing"
        super().__init__(detail_msg)
        self.config_name = config_name


class RepositoryDataError(RepositoryError):
    """リポジトリ内のデータ異常を表す例外."""

    def __init__(self, repository: str, message: str, *, operation: str = "data_validation") -> None:
        super().__init__(repository_name=repository, operation=operation, message=message)
        self.repository = repository
        self.operation = operation


class RepositoryFallbackError(RepositoryError):
    """リポジトリのフォールバック処理に失敗した場合の例外."""

    def __init__(self, repository: str, attempted_fallback: str, message: str | None = None) -> None:
        detail_msg = message or "Repository fallback resolution failed"
        super().__init__(repository_name=repository, operation=attempted_fallback, message=detail_msg)
        self.repository = repository
        self.attempted_fallback = attempted_fallback

__all__ = [
    "BusinessRuleViolationError",
    "ChapterPlotNotFoundError",
    "ConfigurationError",
    # Base exceptions
    "DomainException",
    "DomainValidationError",
    "EpisodeCompletionError",
    "EpisodeNotFoundError",
    "InsufficientDataError",
    "InvalidOperationError",
    "InvalidStatusError",
    "InvalidVersionError",
    "MissingConfigurationError",
    "MissingProjectRootError",
    "NoEpisodesFoundError",
    "PathResolutionError",
    "PlotNotFoundError",
    "ProjectConfigNotFoundError",
    "ProjectNotFoundError",
    "QualityCheckError",
    "QualityRecordError",
    "QualityRecordNotFoundError",
    "RecordTransactionError",
    "RepositoryDataError",
    "RepositoryError",
    "RepositoryFallbackError",
    "StateTransitionError",
    "ValidationError",
    "ViewpointDataInvalidError",
    # Viewpoint exceptions
    "ViewpointError",
    "ViewpointFileNotFoundError",
    "ViewpointRepositoryError",
    "ViewpointYAMLParseError",
]
