import httpx
import pytest

from src import main


@pytest.mark.anyio
async def test_notification_page_endpoint_loads_only_requested_page_and_is_not_cacheable(monkeypatch):
    requested = []

    async def page_loader(page):
        requested.append(page)
        return {
            "items": [{"id": 51, "title": "Older update"}],
            "page": page,
            "total": 125,
            "has_more": True,
        }

    monkeypatch.setattr(main.gitea_proxy, "notification_page", page_loader)
    transport = httpx.ASGITransport(app=main.app)
    async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
        response = await client.get("/api/v1/notifications?page=2")

    assert response.status_code == 200
    assert response.headers["cache-control"] == "no-store"
    assert response.json() == {
        "items": [{"id": 51, "title": "Older update"}],
        "page": 2,
        "total": 125,
        "has_more": True,
    }
    assert requested == [2]


@pytest.mark.anyio
async def test_notification_snapshot_endpoint_returns_one_complete_atomic_no_store_result(monkeypatch):
    requested = []

    async def snapshot_loader(*, deadline_seconds):
        requested.append(deadline_seconds)
        return {
            "items": [
                {"id": 1, "title": "Newest update"},
                {"id": 51, "title": "Older update"},
            ],
            "total": 2,
            "complete": True,
        }

    monkeypatch.setattr(main.gitea_proxy, "unread_notification_snapshot", snapshot_loader)
    transport = httpx.ASGITransport(app=main.app)
    async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
        response = await client.get("/api/v1/notifications/snapshot")

    assert response.status_code == 200
    assert response.headers["cache-control"] == "no-store"
    assert response.json() == {
        "items": [
            {"id": 1, "title": "Newest update"},
            {"id": 51, "title": "Older update"},
        ],
        "total": 2,
        "complete": True,
    }
    assert requested == [main.NOTIFICATION_PAGE_TIMEOUT_SECONDS]


@pytest.mark.anyio
@pytest.mark.parametrize("failure", [TimeoutError(), ValueError("pagination changed")])
async def test_notification_snapshot_endpoint_is_bounded_and_retryable(monkeypatch, failure):
    async def snapshot_loader(*, deadline_seconds):
        raise failure

    monkeypatch.setattr(main.gitea_proxy, "unread_notification_snapshot", snapshot_loader)
    transport = httpx.ASGITransport(app=main.app)
    async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
        response = await client.get("/api/v1/notifications/snapshot")

    assert response.status_code == 503
    assert response.headers["cache-control"] == "no-store"
    assert response.headers["retry-after"] == "1"
    assert response.json() == {
        "error": "Complete unread updates are temporarily unavailable. Please retry."
    }
