import pytest

from src.core.exceptions import (
    PIPException,
    NotFoundException,
    ConflictException,
    ValidationException,
    UnauthorizedException,
    ForbiddenException,
    RateLimitException,
    ServiceUnavailableException,
    ConnectorException,
    SyncException,
)


class TestPIPException:
    def test_base_exception(self):
        exc = PIPException("Something failed", code="TEST_ERROR", status_code=500)
        assert exc.message == "Something failed"
        assert exc.code == "TEST_ERROR"
        assert exc.status_code == 500
        assert "timestamp" in exc.to_dict()["error"]

    def test_not_found(self):
        exc = NotFoundException("Pharmacy", "PH-001")
        assert exc.status_code == 404
        assert exc.code == "NOT_FOUND"
        d = exc.to_dict()
        assert "Pharmacy" in d["error"]["message"]

    def test_conflict(self):
        exc = ConflictException("Duplicate")
        assert exc.status_code == 409

    def test_validation(self):
        exc = ValidationException("Invalid input")
        assert exc.status_code == 422

    def test_unauthorized(self):
        exc = UnauthorizedException()
        assert exc.status_code == 401

    def test_forbidden(self):
        exc = ForbiddenException(required_role="admin")
        assert exc.status_code == 403
        assert exc.details["required_role"] == "admin"

    def test_rate_limit(self):
        exc = RateLimitException()
        assert exc.status_code == 429

    def test_service_unavailable(self):
        exc = ServiceUnavailableException("redis")
        assert exc.status_code == 503
        assert "redis" in exc.details["service"]

    def test_connector_error(self):
        exc = ConnectorException("farmatic", "Connection refused")
        assert exc.status_code == 502
        assert exc.details["connector_type"] == "farmatic"

    def test_sync_error(self):
        exc = SyncException("pharmacy-1", "Timeout")
        assert exc.status_code == 502
        assert exc.details["pharmacy_id"] == "pharmacy-1"
