import pytest

pytestmark = pytest.mark.anyio

# (method, path suffix, json body) for every order endpoint that takes an id
ORDER_ENDPOINTS = [
    ("GET", "", None),
    ("PATCH", "", {"note": "x"}),
    ("POST", "/cancel", None),
    ("GET", "/events", None),
]


@pytest.mark.parametrize("method, suffix, body", ORDER_ENDPOINTS)
async def test_other_customers_orders_do_not_exist(create_order, client, asha, ravi, method, suffix, body):
    order = (await create_order(asha)).json()
    headers = ravi | {"If-Match": f'"{order["id"]}.1"'}
    r = await client.request(method, f"/v1/orders/{order['id']}{suffix}", json=body, headers=headers)
    assert r.status_code == 404                                  # not 403: don't confirm it exists


async def test_lists_are_scoped_to_the_caller(create_order, client, asha, ravi, admin):
    await create_order(asha)
    await create_order(ravi)
    mine = (await client.get("/v1/orders", headers=ravi)).json()["items"]
    everything = (await client.get("/v1/orders", headers=admin)).json()["items"]
    assert [o["customerId"] for o in mine] == [2]
    assert sorted(o["customerId"] for o in everything) == [1, 2]


async def test_customers_cannot_change_status(create_order, client, asha):
    order = (await create_order(asha)).json()
    r = await client.post(f"/v1/orders/{order['id']}/status", json={"status": "completed"},
                          headers=asha | {"If-Match": f'"{order["id"]}.1"'})
    assert r.status_code == 403


async def test_per_user_rate_limit(create_order, client, asha, state):
    state["settings"].rate_limit_per_minute = 3                 # settings object is shared by the app
    statuses = [(await client.get("/v1/orders", headers=asha)).status_code for _ in range(4)]
    assert statuses == [200, 200, 200, 429]


async def test_cors_allows_only_configured_origins(client):
    good = await client.options("/v1/orders", headers={"Origin": "http://localhost:5173",
                                                      "Access-Control-Request-Method": "POST"})
    evil = await client.options("/v1/orders", headers={"Origin": "https://evil.example",
                                                      "Access-Control-Request-Method": "POST"})
    assert good.headers["access-control-allow-origin"] == "http://localhost:5173"
    assert "access-control-allow-origin" not in evil.headers


async def test_docs_are_off_in_production(tmp_path):
    from orders_api.config import Settings
    from orders_api.main import create_app
    with pytest.raises(ValueError, match="JWT_SECRET"):
        Settings(environment="production", seed_demo_data=False)
    settings = Settings(environment="production", seed_demo_data=False, jwt_secret="p" * 40)
    app = create_app(settings)
    assert app.docs_url is None and app.openapi_url is None
