import pytest
from httpx import AsyncClient

from tests.test_sites_crud import Headers, create_site, new_org


async def test_cursor_walks_all_pages_without_duplicates(
    client: AsyncClient, auth_headers: Headers
) -> None:
    headers = auth_headers(new_org())
    created = [
        (await create_site(client, headers, domain=f"site-{i}.exemple.fr"))["id"] for i in range(7)
    ]
    seen: list[str] = []
    cursor: str | None = None
    pages = 0
    while True:
        params: dict[str, str | int] = {"limit": 3}
        if cursor is not None:
            params["cursor"] = cursor
        resp = await client.get("/sites", params=params, headers=headers)
        assert resp.status_code == 200
        data = resp.json()
        seen += [item["id"] for item in data["items"]]
        pages += 1
        cursor = data["next_cursor"]
        if cursor is None:
            break
    assert pages == 3  # 3 + 3 + 1
    assert seen == list(reversed(created))  # plus récent d'abord, ni trou ni doublon


@pytest.mark.parametrize("cursor", ["%%%", "AAAA", "cGFzLXVuLXV1aWQ"])
async def test_malformed_cursor_is_422(
    client: AsyncClient, auth_headers: Headers, cursor: str
) -> None:
    resp = await client.get("/sites", params={"cursor": cursor}, headers=auth_headers(new_org()))
    assert resp.status_code == 422
    assert resp.headers["content-type"].startswith("application/problem+json")


@pytest.mark.parametrize("limit", [0, 101])
async def test_limit_out_of_bounds_is_422(
    client: AsyncClient, auth_headers: Headers, limit: int
) -> None:
    resp = await client.get("/sites", params={"limit": limit}, headers=auth_headers(new_org()))
    assert resp.status_code == 422


async def test_default_limit_is_25(client: AsyncClient, auth_headers: Headers) -> None:
    headers = auth_headers(new_org())
    for i in range(26):
        await create_site(client, headers, domain=f"page-{i}.exemple.fr")
    resp = await client.get("/sites", headers=headers)
    data = resp.json()
    assert len(data["items"]) == 25
    assert data["next_cursor"] is not None
