"""Tests for custom exceptions."""

from __future__ import annotations

from a2a_mesh.exceptions import (
    AgentAlreadyRegisteredError,
    AgentNotFoundError,
    AuthError,
    ConsensusNotReachedError,
    CyclicDependencyError,
    HealthCheckFailedError,
    InsufficientScopeError,
    JsonRpcError,
    MeshError,
    NoCapableAgentError,
    ProtocolError,
    QueueFullError,
    RoutingError,
    TaskExecutionError,
    TokenExpiredError,
    WorkflowError,
)


class TestExceptionHierarchy:
    """Test that all exceptions inherit correctly and carry context."""

    def test_mesh_error_base(self) -> None:
        err = MeshError("something broke", detail="check logs")
        assert str(err) == "something broke"
        assert err.detail == "check logs"

    def test_agent_not_found(self) -> None:
        err = AgentNotFoundError("my-agent")
        assert "my-agent" in str(err)
        assert err.agent_name == "my-agent"
        assert isinstance(err, MeshError)

    def test_agent_already_registered(self) -> None:
        err = AgentAlreadyRegisteredError("my-agent")
        assert "my-agent" in str(err)
        assert isinstance(err, MeshError)

    def test_health_check_failed(self) -> None:
        err = HealthCheckFailedError("agent-x", "timeout")
        assert "agent-x" in str(err)
        assert "timeout" in str(err)

    def test_no_capable_agent(self) -> None:
        err = NoCapableAgentError(["web_search", "nlp"])
        assert "web_search" in str(err)
        assert err.capabilities == ["web_search", "nlp"]

    def test_queue_full(self) -> None:
        err = QueueFullError("busy-agent", 100)
        assert "busy-agent" in str(err)
        assert isinstance(err, RoutingError)

    def test_cyclic_dependency(self) -> None:
        err = CyclicDependencyError(["a", "b", "c"])
        assert "a -> b -> c" in str(err)
        assert isinstance(err, WorkflowError)

    def test_task_execution_error(self) -> None:
        err = TaskExecutionError("step1", "timeout")
        assert "step1" in str(err)
        assert isinstance(err, WorkflowError)

    def test_consensus_not_reached(self) -> None:
        err = ConsensusNotReachedError("review", 1, 3)
        assert "1/3" in str(err)
        assert err.received == 1
        assert err.required == 3

    def test_token_expired(self) -> None:
        err = TokenExpiredError()
        assert "expired" in str(err).lower()
        assert isinstance(err, AuthError)

    def test_insufficient_scope(self) -> None:
        err = InsufficientScopeError(["admin"], ["read"])
        assert isinstance(err, AuthError)
        assert err.required == ["admin"]
        assert err.provided == ["read"]

    def test_json_rpc_error(self) -> None:
        err = JsonRpcError(-32600, "Invalid request")
        assert err.code == -32600
        assert isinstance(err, ProtocolError)
