"""User-perspective tests for ``mgf.apiprobe.checks``.

Surfaces exercised:
  - All 22 check classes importable from the public path.
  - ``DEFAULT_CHECKS`` is a tuple containing one of each check.
  - Every check exposes a stable, dotted-namespace ``code``
    attribute (the public contract — codes don't rename without
    a breaking-change cycle).
"""

from __future__ import annotations

from mgf.apiprobe.checks import (
    DEFAULT_CHECKS,
    BodyEchoesSecret,
    BodyEmptyOnSuccess,
    BodyInvalidJson,
    BodySizeOverBudget,
    ContentTypeJsonExpected,
    ContentTypeMissing,
    HeaderMissing,
    LatencyOverBudget,
    LatencySuspiciousZero,
    MissingContentTypeOptions,
    MissingFrameOptions,
    MissingHsts,
    MissingRateLimitHeaders,
    MissingRequestId,
    MissingServerHeader,
    SchemaShapeMismatch,
    Server5xx,
    StatusUnexpected,
)

_ALL_CHECK_CLASSES = (
    StatusUnexpected,
    Server5xx,
    HeaderMissing,
    ContentTypeMissing,
    ContentTypeJsonExpected,
    SchemaShapeMismatch,
    BodyInvalidJson,
    BodyEmptyOnSuccess,
    LatencyOverBudget,
    LatencySuspiciousZero,
    BodySizeOverBudget,
    MissingHsts,
    MissingContentTypeOptions,
    MissingFrameOptions,
    BodyEchoesSecret,
    MissingRequestId,
    MissingRateLimitHeaders,
    MissingServerHeader,
)


class TestDefaultChecks:
    def test_default_checks_is_tuple(self) -> None:
        assert isinstance(DEFAULT_CHECKS, tuple)
        assert len(DEFAULT_CHECKS) == 22

    def test_default_checks_covers_every_class(self) -> None:
        # Each public check class has at least one instance in DEFAULT_CHECKS.
        types_in_default = {type(c) for c in DEFAULT_CHECKS}
        for cls in _ALL_CHECK_CLASSES:
            assert cls in types_in_default, f"{cls.__name__} not represented in DEFAULT_CHECKS"


class TestCheckCodes:
    def test_each_default_check_has_a_code(self) -> None:
        for c in DEFAULT_CHECKS:
            assert hasattr(c, "code"), f"{type(c).__name__} missing code"
            assert isinstance(c.code, str)
            # Dotted namespace, e.g. "contract.status.unexpected".
            assert "." in c.code, f"{type(c).__name__} has non-namespaced code {c.code!r}"

    def test_codes_are_unique(self) -> None:
        codes = [c.code for c in DEFAULT_CHECKS]
        assert len(codes) == len(set(codes)), "DEFAULT_CHECKS contains duplicate codes"

    def test_codes_are_grouped_by_category(self) -> None:
        # The first segment of each code is its category. Verify the
        # five known categories are represented.
        categories = {c.code.split(".", 1)[0] for c in DEFAULT_CHECKS}
        expected = {
            "contract",  # status / header / content-type
            "schema",  # body / shape
            "quality",  # latency / size
            "security",  # headers / body echo
            "observability",  # request-id / rate-limit / server
        }
        assert categories == expected, (
            f"DEFAULT_CHECKS categories drift: got {categories}, expected {expected}"
        )
