"""Error hierarchy for the LSP subsystem.

Provides domain-specific exceptions for the Language Server Protocol
integration layer.  All errors inherit from
:class:`~cleveragents.core.exceptions.CleverAgentsError` and follow
the project-wide fail-fast conventions (ADR-005).

Error Classes
-------------
| Error                    | When raised                              |
|--------------------------|------------------------------------------|
| ``LspError``             | Base for all LSP errors                  |
| ``LspNotAvailableError`` | LSP operation attempted in local mode    |
| ``LspServerNotFoundError``| Named LSP server not in registry        |
"""

from __future__ import annotations

from typing import Any

from cleveragents.core.exceptions import CleverAgentsError


class LspError(CleverAgentsError):
    """Base exception for all LSP-related errors."""

    def __init__(self, message: str, details: dict[str, Any] | None = None) -> None:
        super().__init__(message, details)


class LspNotAvailableError(LspError):
    """Raised when an LSP operation is attempted in local mode.

    In local mode the LSP Runtime does not start real language servers.
    All runtime and tool-adapter operations raise this error with a
    descriptive message directing users to server mode.
    """

    def __init__(
        self,
        message: str = "LSP is not available in local mode",
        details: dict[str, Any] | None = None,
    ) -> None:
        super().__init__(message, details)


class LspServerNotFoundError(LspError):
    """Raised when a referenced LSP server is not in the registry.

    Attributes:
        server_name: The namespaced server name that was not found.
    """

    def __init__(
        self,
        server_name: str,
        details: dict[str, Any] | None = None,
    ) -> None:
        if not server_name:
            raise ValueError("server_name must be a non-empty string")
        msg = f"LSP server '{server_name}' not found in registry"
        super().__init__(msg, details)
        self.server_name = server_name


__all__ = [
    "LspError",
    "LspNotAvailableError",
    "LspServerNotFoundError",
]
