"""Тесты DoH-провайдера SystemDNS."""

from __future__ import annotations

import asyncio

import httpx

from ioc_checker.iocs.domain import DOMAINIndicator
from ioc_checker.iocs.ip import IPAddressIndicator
from ioc_checker.providers.systemdns import RECORD_TYPES, SystemDNSProvider


def _build_doh_transport(responses: dict[str, list[str]]) -> httpx.MockTransport:
    def _handler(request: httpx.Request) -> httpx.Response:  # noqa: ANN001
        params = dict(request.url.params)
        record_type = params.get("type")
        assert request.url.path == "/resolve"

        answer = responses.get(record_type)
        payload = {"Status": 0}
        if answer:
            payload["Answer"] = [{"data": value} for value in answer]
        return httpx.Response(200, json=payload)

    return httpx.MockTransport(_handler)


def test_systemdns_fetch_uses_doh_and_returns_records() -> None:
    doh_responses = {
        "A": ["93.184.216.34"],
        "TXT": ["v=spf1 include:_spf.example.com ~all"],
    }
    provider = SystemDNSProvider(transport=_build_doh_transport(doh_responses))
    indicator = DOMAINIndicator(value="example.com", kinds=frozenset())

    async def _run() -> dict[str, list[str]] | bool:
        async with provider.get_context() as client:
            return await provider.fetch(indicator, client)

    payload = asyncio.run(_run())

    assert payload["A"] == ["93.184.216.34"]
    assert payload["TXT"] == ["v=spf1 include:_spf.example.com ~all"]
    for record_type in RECORD_TYPES:
        assert record_type in payload


def test_systemdns_fetch_skips_non_domain_without_requests() -> None:
    def _failing_handler(request: httpx.Request) -> httpx.Response:  # noqa: ANN001
        raise AssertionError(f"Неожиданный запрос {request.url}")

    provider = SystemDNSProvider(transport=httpx.MockTransport(_failing_handler))
    indicator = IPAddressIndicator(value="1.1.1.1", kinds=frozenset())

    result = asyncio.run(provider.fetch(indicator, context=None))

    assert result is False


def test_systemdns_fetch_handles_http_errors() -> None:
    def _error_handler(request: httpx.Request) -> httpx.Response:  # noqa: ANN001
        return httpx.Response(500, json={"Status": 2})

    provider = SystemDNSProvider(transport=httpx.MockTransport(_error_handler))
    indicator = DOMAINIndicator(value="broken.example", kinds=frozenset())

    async def _run() -> dict[str, list[str]] | bool:
        async with provider.get_context() as client:
            return await provider.fetch(indicator, client)

    result = asyncio.run(_run())

    assert result is False
