"""Fake service objects for testing.

Production-importable fakes that replace external dependencies
(HTTP fetchers, font downloaders) with deterministic, offline
alternatives. Importable from any test without redeclaring mocks.

See ADR 019, item 14.
"""

from __future__ import annotations

from dataclasses import dataclass, field


@dataclass
class FakeBrandFetcher:
    """Offline stand-in for ``brand_from_url.fetch_url``.

    Usage::

        fake = FakeBrandFetcher(responses={"https://acme.com": "<html>...</html>"})
        monkeypatch.setattr("tokenmoulds.brand_from_url.fetch_url", fake.fetch)
    """

    responses: dict[str, str] = field(default_factory=dict)
    calls: list[str] = field(default_factory=list)
    default_html: str = "<html><body></body></html>"

    def fetch(self, url: str, timeout: int = 30) -> str:
        self.calls.append(url)
        return self.responses.get(url, self.default_html)


@dataclass
class OfflineFontFetcher:
    """Offline stand-in for font download services.

    Maps URLs to local file paths. Returns None for unknown URLs.

    Usage::

        fake = OfflineFontFetcher(url_to_path={"https://fonts.example.com/Inter.ttf": "/fonts/Inter.ttf"})
        result = fake.fetch("https://fonts.example.com/Inter.ttf")
    """

    url_to_path: dict[str, str] = field(default_factory=dict)
    calls: list[str] = field(default_factory=list)

    def fetch(self, url: str) -> str | None:
        self.calls.append(url)
        return self.url_to_path.get(url)
