"""Tests for the exception hierarchy and HTTP mapping."""
from src.core.exceptions import (
    ConflictError,
    ForbiddenError,
    InvitePathMismatchError,
    MfaRequiredError,
    NotFoundError,
    P2HSError,
    PaymentRequiredError,
    PlanLimitError,
    RateLimitError,
    UnauthorizedError,
    ValidationError,
    to_http_exception,
)


def test_base_error():
    err = P2HSError("something broke")
    assert err.message == "something broke"
    assert err.code == "INTERNAL_ERROR"


def test_not_found_defaults():
    err = NotFoundError()
    assert err.code == "NOT_FOUND"
    http = to_http_exception(err)
    assert http.status_code == 404


def test_forbidden_defaults():
    err = ForbiddenError()
    http = to_http_exception(err)
    assert http.status_code == 403


def test_unauthorized_defaults():
    err = UnauthorizedError()
    http = to_http_exception(err)
    assert http.status_code == 401


def test_conflict_defaults():
    err = ConflictError()
    http = to_http_exception(err)
    assert http.status_code == 409


def test_validation_error():
    err = ValidationError("bad input")
    http = to_http_exception(err)
    assert http.status_code == 422


def test_rate_limit_error():
    err = RateLimitError()
    http = to_http_exception(err)
    assert http.status_code == 429


def test_custom_message():
    err = NotFoundError("Project not found")
    assert err.message == "Project not found"
    http = to_http_exception(err)
    assert "Project not found" in str(http.detail)


def test_payment_required_error():
    err = PaymentRequiredError(
        message="Active subscription required",
        workspace_id="ws-123",
        billing_status="past_due",
    )
    http = to_http_exception(err)
    assert http.status_code == 402
    assert http.detail.get("workspace_id") == "ws-123"
    assert http.detail.get("billing_status") == "past_due"


def test_mfa_required_error():
    err = MfaRequiredError(message="MFA required", workspace_id="ws-456")
    http = to_http_exception(err)
    assert http.status_code == 403
    assert http.detail.get("workspace_id") == "ws-456"


def test_plan_limit_error():
    err = PlanLimitError(
        message="This plan allows up to 5 members.",
        limit_code="max_members",
        current_count=5,
        max_allowed=5,
    )
    http = to_http_exception(err)
    assert http.status_code == 403
    assert http.detail.get("limit_code") == "max_members"
    assert http.detail.get("current_count") == 5
    assert http.detail.get("max_allowed") == 5


def test_invite_path_mismatch_error():
    err = InvitePathMismatchError(
        message="Invite token does not belong to this workspace.",
        workspace_id="ws-456",
    )
    http = to_http_exception(err)
    assert http.status_code == 422
    assert http.detail.get("workspace_id") == "ws-456"
