from unittest.mock import MagicMock

import httpx
import pytest

from govcrawler.fetcher import http_client as hc
from govcrawler.fetcher.browser import FetchResult


@pytest.fixture(autouse=True)
def _env(monkeypatch):
    monkeypatch.setenv("DB_URL", "postgresql+psycopg://x/x")
    monkeypatch.setenv("USER_AGENT", "TestBot/1.0")


def _fake_client(response):
    class _Ctx:
        def __enter__(self_inner):
            return self_inner

        def __exit__(self_inner, *a):
            pass

        def get(self_inner, url):
            return response

    def factory(**kw):
        return _Ctx()

    return factory


def test_httpx_happy_path(monkeypatch):
    resp = MagicMock()
    resp.status_code = 200
    resp.text = "<html>" + "x" * 1000 + "</html>"
    resp.url = "https://a.com/ok"
    resp.headers = {"content-type": "text/html; charset=utf-8"}
    monkeypatch.setattr(hc.httpx, "Client", _fake_client(resp))

    fr = hc.fetch_html_http("https://a.com/x")
    assert fr.strategy == "httpx"
    assert fr.status == 200
    assert fr.is_challenge is False
    assert fr.html.startswith("<html")


def test_httpx_detects_challenge_412(monkeypatch):
    resp = MagicMock()
    resp.status_code = 412
    resp.text = "<html><title>请稍候</title></html>"
    resp.url = "https://a.com/x"
    resp.headers = {"content-type": "text/html"}
    monkeypatch.setattr(hc.httpx, "Client", _fake_client(resp))

    fr = hc.fetch_html_http("https://a.com/x")
    assert fr.is_challenge is True
    assert fr.status == 412


def test_httpx_exception_recorded(monkeypatch):
    class _Ctx:
        def __enter__(self_inner):
            return self_inner

        def __exit__(self_inner, *a):
            pass

        def get(self_inner, url):
            raise httpx.ConnectError("boom")

    monkeypatch.setattr(hc.httpx, "Client", lambda **kw: _Ctx())
    fr = hc.fetch_html_http("https://a.com/x")
    assert fr.error and "ConnectError" in fr.error
    assert fr.strategy == "httpx"
    assert fr.status == 0
