"""Orchestrator error hierarchy."""

from __future__ import annotations


class OrchestratorError(Exception):
    """Base exception for all orchestrator errors."""


class ClaudeCliNotFoundError(OrchestratorError):
    """The `claude` CLI binary was not found on PATH."""


class BudgetExceededError(OrchestratorError):
    """Total or per-child cost budget has been exceeded."""

    def __init__(self, spent: float, limit: float, message: str | None = None) -> None:
        self.spent = spent
        self.limit = limit
        super().__init__(message or f"Budget exceeded: ${spent:.2f} spent, limit ${limit:.2f}")


class TimeoutExceededError(OrchestratorError):
    """Total or per-child time budget has been exceeded."""

    def __init__(self, elapsed: float, limit: float, message: str | None = None) -> None:
        self.elapsed = elapsed
        self.limit = limit
        super().__init__(message or f"Timeout exceeded: {elapsed:.0f}s elapsed, limit {limit:.0f}s")


class CircuitBreakerTrippedError(OrchestratorError):
    """Too many consecutive child failures."""

    def __init__(self, failures: int, threshold: int) -> None:
        self.failures = failures
        self.threshold = threshold
        super().__init__(
            f"Circuit breaker tripped: {failures} consecutive failures (threshold: {threshold})"
        )


class GitWorktreeError(OrchestratorError):
    """Git worktree operation failed."""


class MergeConflictError(OrchestratorError):
    """Git merge produced conflicts that could not be auto-resolved."""

    def __init__(self, branch: str, conflicts: list[str] | None = None) -> None:
        self.branch = branch
        self.conflicts = conflicts or []
        files = ", ".join(self.conflicts[:5]) if self.conflicts else "unknown files"
        super().__init__(f"Merge conflict on branch {branch}: {files}")


class PlanningFailedError(OrchestratorError):
    """Claude planning phase failed to produce a valid split strategy."""


class ResumeError(OrchestratorError):
    """Failed to resume from saved orchestrator state."""
