"""Contract tests for HostContext.

These tests verify that HostContext satisfies the architectural requirements:
- Minimal (3 fields maximum)
- Frozen dataclass
- config_dir: Path
- logger: Logger
- http_client: HttpClient protocol
"""

import logging
from pathlib import Path

import pytest

from abogen.tts_plugin.host_context import HttpClient, HostContext


class TestHostContextContract:
    """Contract tests for HostContext dataclass."""

    def test_is_frozen_dataclass(self) -> None:
        assert hasattr(HostContext, "__dataclass_params__")
        assert HostContext.__dataclass_params__.frozen is True

    def test_required_fields(self, tmp_path: Path) -> None:
        logger = logging.getLogger("test")

        class FakeClient:
            def get(self, url: str, **kwargs: object) -> object:
                return None

            def post(self, url: str, **kwargs: object) -> object:
                return None

        ctx = HostContext(
            config_dir=tmp_path,
            logger=logger,
            http_client=FakeClient(),
        )
        assert ctx.config_dir == tmp_path
        assert ctx.logger is logger

    def test_immutability(self, tmp_path: Path) -> None:
        class FakeClient:
            def get(self, url: str, **kwargs: object) -> object:
                return None

            def post(self, url: str, **kwargs: object) -> object:
                return None

        ctx = HostContext(
            config_dir=tmp_path,
            logger=logging.getLogger("test"),
            http_client=FakeClient(),
        )
        with pytest.raises(AttributeError):
            ctx.config_dir = Path("/other")  # type: ignore[misc]

    def test_max_three_fields(self) -> None:
        """Architecture spec: HostContext is minimal (3 fields max)."""
        import dataclasses

        fields = dataclasses.fields(HostContext)
        assert len(fields) <= 3


class TestHttpClientProtocolContract:
    """Contract tests for HttpClient protocol."""

    def test_http_client_is_protocol(self) -> None:
        assert hasattr(HttpClient, "__protocol_attrs__")

    def test_http_client_has_get(self) -> None:
        assert hasattr(HttpClient, "get")

    def test_http_client_has_post(self) -> None:
        assert hasattr(HttpClient, "post")

    def test_http_client_satisfied(self) -> None:
        class FakeClient:
            def get(self, url: str, **kwargs: object) -> object:
                return None

            def post(self, url: str, **kwargs: object) -> object:
                return None

        client = FakeClient()
        assert isinstance(client, HttpClient)
