"""DELETE /catalog/products wipes a tenant's whole catalogue -- products,
pairings, and embeddings -- and disconnects every source the tenant had
connected, so a still-connected source can't silently repopulate what was
just deleted on the next build."""
from unittest.mock import patch

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient

from app.api import catalog as catalog_api


@pytest.fixture
def client():
    app = FastAPI()
    app.include_router(catalog_api.router)
    return TestClient(app)


def test_wipes_everything_and_reports_counts(client):
    with patch.object(catalog_api, "delete_all_products",
                      return_value={"products": 27, "pairings": 105, "embeddings": 27}) as wipe, \
         patch.object(catalog_api, "disconnect_all_sources", return_value=2) as disconnect:
        resp = client.delete("/catalog/products", params={"tenant_id": "org_x"})

    assert resp.status_code == 200
    assert resp.json() == {"products": 27, "pairings": 105, "embeddings": 27,
                           "sources_disconnected": 2}
    wipe.assert_called_once_with("org_x")
    disconnect.assert_called_once_with("org_x")


def test_an_already_empty_catalogue_still_succeeds(client):
    with patch.object(catalog_api, "delete_all_products",
                      return_value={"products": 0, "pairings": 0, "embeddings": 0}), \
         patch.object(catalog_api, "disconnect_all_sources", return_value=0):
        resp = client.delete("/catalog/products", params={"tenant_id": "org_x"})

    assert resp.status_code == 200
    assert resp.json() == {"products": 0, "pairings": 0, "embeddings": 0,
                           "sources_disconnected": 0}


def test_does_not_collide_with_the_single_product_delete_route(client):
    # DELETE /catalog/products (bulk) and DELETE /catalog/products/{key}
    # (single) must resolve to different handlers.
    with patch.object(catalog_api, "delete_all_products", return_value={}) as wipe, \
         patch.object(catalog_api, "disconnect_all_sources", return_value=0), \
         patch.object(catalog_api, "delete_product") as delete_one:
        client.delete("/catalog/products", params={"tenant_id": "org_x"})

    wipe.assert_called_once()
    delete_one.assert_not_called()


def test_products_are_wiped_even_if_no_sources_were_connected(client):
    with patch.object(catalog_api, "delete_all_products",
                      return_value={"products": 5, "pairings": 0, "embeddings": 5}), \
         patch.object(catalog_api, "disconnect_all_sources", return_value=0) as disconnect:
        resp = client.delete("/catalog/products", params={"tenant_id": "org_x"})

    assert resp.json()["sources_disconnected"] == 0
    disconnect.assert_called_once_with("org_x")
