"""Self-check for the concurrent dealgod.supply() batcher. No network — fake httpx client.
Run: .venv/bin/python test_dealgod_supply.py"""
import asyncio
import app.dealgod as dg

SEEN = []          # batches the fake client received


class _Resp:
    status_code = 200

    def __init__(self, ids):
        self.ids = ids

    def json(self):
        return {"results": {str(i): {"n": 1} for i in self.ids}}


class _FakeClient:
    def __init__(self, *a, **k):
        pass

    async def __aenter__(self):
        return self

    async def __aexit__(self, *a):
        return False

    async def post(self, url, json=None):
        ids = json["ids"]
        SEEN.append(list(ids))
        if -1 in ids:                          # poison sentinel → simulate a failing batch
            raise RuntimeError("simulated batch failure")
        return _Resp(ids)


async def _fake_key(db):
    return "fake-key"


def test_supply():
    orig_client, orig_key = dg.httpx.AsyncClient, dg._key
    dg.httpx.AsyncClient, dg._key = _FakeClient, _fake_key
    try:
        # 450 ids → 3 batches (200/200/50), all results merged
        SEEN.clear()
        res = asyncio.run(dg.supply(None, list(range(450))))
        assert len(SEEN) == 3, SEEN
        assert sorted(len(b) for b in SEEN) == [50, 200, 200]
        assert len(res) == 450 and res["0"] == {"n": 1} and res["449"] == {"n": 1}

        # empty ids → {} with zero calls
        SEEN.clear()
        assert asyncio.run(dg.supply(None, [])) == {} and SEEN == []

        # ONE failing batch among several is dropped; the others still merge (isolation)
        SEEN.clear()
        ids2 = list(range(200)) + [-1] + list(range(201, 250))   # batch 2 holds the poison
        res2 = asyncio.run(dg.supply(None, ids2))
        assert len(SEEN) == 2
        assert len(res2) == 200 and "0" in res2 and "201" not in res2
        print("ok — concurrent batching, merge, empty-guard, degrade-isolation all pass")
    finally:
        dg.httpx.AsyncClient, dg._key = orig_client, orig_key


if __name__ == "__main__":
    test_supply()
