"""Unit tests for Novyx SDK exceptions."""
import pytest
from novyx import (
    NovyxError,
    NovyxAuthError,
    NovyxForbiddenError,
    NovyxRateLimitError,
    NovyxNotFoundError,
    NovyxSecurityError,
    NovyxUpgradeRequired,
)


def test_base_exception():
    """Test base NovyxError."""
    err = NovyxError("Test error")
    assert str(err) == "Test error"
    assert isinstance(err, Exception)


def test_auth_error():
    """Test NovyxAuthError."""
    err = NovyxAuthError("Invalid API key")
    assert str(err) == "Invalid API key"
    assert isinstance(err, NovyxError)


def test_forbidden_error():
    """Test NovyxForbiddenError with data."""
    data = {
        "feature": "rollback",
        "tier_required": "pro",
        "upgrade_url": "https://novyxlabs.com/pricing"
    }
    err = NovyxForbiddenError("Pro tier required", data)

    assert str(err) == "Pro tier required"
    assert err.feature == "rollback"
    assert err.tier_required == "pro"
    assert err.upgrade_url == "https://novyxlabs.com/pricing"


def test_rate_limit_error():
    """Test NovyxRateLimitError with limit details."""
    data = {
        "limit": "api_calls",
        "current": 5000,
        "max": 5000,
        "tier": "free",
        "upgrade_url": "https://novyxlabs.com/pricing",
        "retry_after": 3600
    }
    err = NovyxRateLimitError("Rate limit exceeded", data)

    assert str(err) == "Rate limit exceeded"
    assert err.limit_type == "api_calls"
    assert err.current == 5000
    assert err.limit == 5000
    assert err.tier == "free"
    assert err.retry_after == 3600
    assert err.upgrade_url == "https://novyxlabs.com/pricing"


def test_rate_limit_error_no_data():
    """Test NovyxRateLimitError without data dict."""
    err = NovyxRateLimitError("Rate limit exceeded")

    assert str(err) == "Rate limit exceeded"
    assert err.current is None
    assert err.limit is None
    assert err.upgrade_url == "https://novyxlabs.com/pricing"


def test_not_found_error():
    """Test NovyxNotFoundError."""
    err = NovyxNotFoundError("Memory not found")
    assert str(err) == "Memory not found"
    assert isinstance(err, NovyxError)


def test_security_error():
    """Test NovyxSecurityError."""
    err = NovyxSecurityError("Policy violation")
    assert str(err) == "Policy violation"
    assert isinstance(err, NovyxError)


def test_upgrade_required_legacy():
    """Test NovyxUpgradeRequired (legacy alias)."""
    data = {"current": 100, "limit": 100}
    err = NovyxUpgradeRequired("Upgrade required", data)

    # Should be instance of both
    assert isinstance(err, NovyxRateLimitError)
    assert isinstance(err, NovyxUpgradeRequired)
    assert err.current == 100


def test_exception_hierarchy():
    """Test exception hierarchy."""
    # All custom exceptions should inherit from NovyxError
    assert issubclass(NovyxAuthError, NovyxError)
    assert issubclass(NovyxForbiddenError, NovyxError)
    assert issubclass(NovyxRateLimitError, NovyxError)
    assert issubclass(NovyxNotFoundError, NovyxError)
    assert issubclass(NovyxSecurityError, NovyxError)

    # NovyxUpgradeRequired is an alias of NovyxRateLimitError
    assert issubclass(NovyxUpgradeRequired, NovyxRateLimitError)
