import httpx

from govcrawler import openstd_download


class _FakeResponse:
    def __init__(self, status_code=200, content=b"", headers=None, text=None):
        self.status_code = status_code
        self.content = content
        self.headers = headers or {}
        self.text = text if text is not None else content.decode("utf-8", "ignore")

    def raise_for_status(self):
        if self.status_code >= 400:
            request = httpx.Request("GET", "http://c.gb688.cn/bzgk/gb/showGb")
            response = httpx.Response(self.status_code, request=request)
            raise httpx.HTTPStatusError("bad status", request=request, response=response)


class _FakeClient:
    def __init__(self, show_exc=None, show_status=200):
        self.closed = False
        self.show_exc = show_exc
        self.show_status = show_status
        self.calls = []

    def get(self, url, **kwargs):
        self.calls.append(("get", url, kwargs))
        if url == "showGb":
            if self.show_exc is not None:
                raise self.show_exc
            return _FakeResponse(status_code=self.show_status, content=b"missing")
        if url.startswith("gc?_="):
            return _FakeResponse(
                content=b"jpeg",
                headers={"content-type": "image/jpeg"},
            )
        raise AssertionError(url)

    def close(self):
        self.closed = True


def test_start_session_keeps_going_when_legacy_showgb_resets(monkeypatch):
    client = _FakeClient(show_exc=httpx.ConnectError("reset"))
    monkeypatch.setattr(openstd_download, "_new_client", lambda: client)

    sess = openstd_download.start_session("8DFBEDE88D831247BF30901B1B42E8D0", article_id=123)
    try:
        assert sess.article_id == 123
        assert sess.captcha_bytes == b"jpeg"
        assert sess.captcha_content_type == "image/jpeg"
        assert client.closed is False
    finally:
        openstd_download.close_session(sess.session_id)


def test_start_session_accepts_legacy_showgb_404_when_captcha_works(monkeypatch):
    client = _FakeClient(show_status=404)
    monkeypatch.setattr(openstd_download, "_new_client", lambda: client)

    sess = openstd_download.start_session("8DFBEDE88D831247BF30901B1B42E8D0", article_id=123)
    try:
        assert sess.captcha_bytes == b"jpeg"
        assert client.calls[0][1] == "showGb"
        assert client.calls[1][1].startswith("gc?_=")
    finally:
        openstd_download.close_session(sess.session_id)
