import pytest
from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)
TENANT = "org_8c32bf3e-6a18-4739-9b1c-94c0cf11125f"


def test_tenant_id_is_required():
    assert client.post("/catalog/enrich", data={}).status_code == 422


def test_route_is_registered():
    assert "/catalog/enrich" in set(app.openapi()["paths"])


def test_returns_the_report(monkeypatch):
    # wait=true keeps the pre-job-polling contract: synchronous, report inline.
    from app.api import endpoints
    monkeypatch.setattr(endpoints, "enrich_tenant", lambda t, force=False: {
        "products": 218, "extracted": 211, "skipped_unextractable": 7,
        "failed": 0, "conflicts": 3})

    resp = client.post("/catalog/enrich", data={"tenant_id": TENANT, "wait": "true"})
    assert resp.status_code == 200
    assert resp.json()["extracted"] == 211


def test_force_is_passed_through(monkeypatch):
    from app.api import endpoints
    seen = {}
    monkeypatch.setattr(endpoints, "enrich_tenant",
                        lambda t, force=False: seen.update(force=force) or {})

    client.post("/catalog/enrich",
               data={"tenant_id": TENANT, "force": "true", "wait": "true"})
    assert seen["force"] is True


def test_a_failure_returns_502_not_500(monkeypatch):
    # Enrichment is a background-ish operation; a model outage is an upstream
    # fault, not a bug in this service. wait=true keeps the old synchronous
    # contract, where that fault surfaces as a 502 on this same request.
    from app.api import endpoints

    def boom(t, force=False):
        raise RuntimeError("model unavailable")

    monkeypatch.setattr(endpoints, "enrich_tenant", boom)
    resp = client.post("/catalog/enrich", data={"tenant_id": TENANT, "wait": "true"})
    assert resp.status_code == 502
    assert "RuntimeError" in resp.text          # class name only, no detail
