"""Error types for the local MCP server.

Uses the arcade-tdk error hierarchy:
- FatalToolError: Non-recoverable errors (bad input, missing files, security)
- RetryableToolError: Transient errors that may succeed on retry (timeouts)
"""

from arcade_tdk.errors import FatalToolError, RetryableToolError


class PathNotFoundError(FatalToolError):
    """Raised when a requested path does not exist.

    Examples:
        - File to read doesn't exist
        - Directory to list doesn't exist
        - Working directory for command doesn't exist
    """

    def __init__(self, path: str, message: str | None = None):
        self.path = path
        super().__init__(message or f"Path not found: {path}")


class PathSecurityError(FatalToolError):
    """Raised when a path operation is denied for security reasons.

    Examples:
        - Attempting to write outside project root
        - Attempting to access restricted paths
    """

    def __init__(self, path: str, reason: str | None = None):
        self.path = path
        msg = f"Access denied: {path}"
        if reason:
            msg += f" ({reason})"
        super().__init__(msg)


class InvalidInputError(FatalToolError):
    """Raised when tool input is invalid.

    Examples:
        - Empty search pattern
        - Invalid line number
        - Malformed arguments
    """

    def __init__(self, parameter: str, message: str):
        self.parameter = parameter
        super().__init__(f"Invalid {parameter}: {message}")


class CommandTimeoutError(RetryableToolError):
    """Raised when a command or operation times out.

    This is retryable because timeouts may be transient.
    """

    def __init__(self, command: str, timeout_seconds: int):
        self.command = command
        self.timeout_seconds = timeout_seconds
        super().__init__(f"Command timed out after {timeout_seconds}s: {command[:50]}...")


class CommandExecutionError(FatalToolError):
    """Raised when command execution fails.

    Examples:
        - Shell command returns non-zero exit code with error
        - Command binary not found
        - Permission denied
    """

    def __init__(self, command: str, message: str, exit_code: int | None = None):
        self.command = command
        self.exit_code = exit_code
        detail = f" (exit code: {exit_code})" if exit_code is not None else ""
        super().__init__(f"Command failed{detail}: {message}")


class GitOperationError(FatalToolError):
    """Raised when a git operation fails.

    Examples:
        - Not a git repository
        - Branch doesn't exist
        - Merge conflict
    """

    def __init__(self, operation: str, message: str):
        self.operation = operation
        super().__init__(f"Git {operation} failed: {message}")


class SearchError(FatalToolError):
    """Raised when a search operation fails.

    Examples:
        - Invalid regex pattern
        - Search tool not installed
    """

    def __init__(self, tool: str, message: str):
        self.tool = tool
        super().__init__(f"Search failed ({tool}): {message}")


class FileOperationError(FatalToolError):
    """Raised when a file operation fails.

    Examples:
        - Cannot read file (encoding issues)
        - Cannot write file (permissions)
        - Edit operation failed
    """

    def __init__(self, operation: str, path: str, message: str):
        self.operation = operation
        self.path = path
        super().__init__(f"Failed to {operation} '{path}': {message}")
