# retoor <retoor@molodetz.nl>

import requests
from tests.conftest import BASE_URL
from devplacepy.database import get_table, refresh_snapshot
from devplacepy.services.jobs import queue


def _json_headers():
    return {"Accept": "application/json"}


def _clear_deepsearch_jobs():
    refresh_snapshot()
    jobs = get_table("jobs")
    for row in list(jobs.find(kind="deepsearch")):
        jobs.delete(uid=row["uid"])
    sessions = get_table("deepsearch_sessions")
    for row in list(sessions.find()):
        sessions.delete(uid=row["uid"])


def test_deepsearch_page_renders(app_server):
    r = requests.get(f"{BASE_URL}/tools/deepsearch")
    assert r.status_code == 200
    assert "DeepSearch" in r.text
    assert "data-deepsearch-form" in r.text


def test_run_enqueues_and_returns_uid(app_server):
    try:
        r = requests.post(
            f"{BASE_URL}/tools/deepsearch/run",
            headers=_json_headers(),
            data={"query": "history of the transistor", "depth": "2", "max_pages": "5"},
        )
        assert r.status_code == 200, r.text
        body = r.json()
        uid = body["uid"]
        assert uid
        assert body["status_url"] == f"/tools/deepsearch/{uid}"
        assert body["ws_url"] == f"/tools/deepsearch/{uid}/ws"

        refresh_snapshot()
        job = queue.get_job(uid)
        assert job is not None
        assert job["kind"] == "deepsearch"
        assert job["status"] == queue.PENDING
        assert job["payload"]["query"] == "history of the transistor"
        assert job["payload"]["max_pages"] == 5
        assert job["payload"]["api_key"]

        session = get_table("deepsearch_sessions").find_one(uid=uid)
        assert session is not None
        assert session["status"] == "pending"
    finally:
        _clear_deepsearch_jobs()


def test_run_rejects_blank_query(app_server):
    try:
        r = requests.post(
            f"{BASE_URL}/tools/deepsearch/run",
            headers=_json_headers(),
            data={"query": "  ", "depth": "2"},
            allow_redirects=False,
        )
        assert r.status_code in (400, 422), r.text
    finally:
        _clear_deepsearch_jobs()


def test_run_rejects_depth_above_cap(app_server):
    try:
        r = requests.post(
            f"{BASE_URL}/tools/deepsearch/run",
            headers=_json_headers(),
            data={"query": "valid question", "depth": "99"},
            allow_redirects=False,
        )
        assert r.status_code in (400, 422), r.text
    finally:
        _clear_deepsearch_jobs()


def test_run_rejects_max_pages_above_cap(app_server):
    try:
        r = requests.post(
            f"{BASE_URL}/tools/deepsearch/run",
            headers=_json_headers(),
            data={"query": "valid question", "max_pages": "9999"},
            allow_redirects=False,
        )
        assert r.status_code in (400, 422), r.text
    finally:
        _clear_deepsearch_jobs()


def test_run_enforces_one_active_job_per_owner(app_server):
    try:
        first = requests.post(
            f"{BASE_URL}/tools/deepsearch/run",
            headers=_json_headers(),
            data={"query": "first question"},
        )
        assert first.status_code == 200, first.text
        first_uid = first.json()["uid"]

        second = requests.post(
            f"{BASE_URL}/tools/deepsearch/run",
            headers=_json_headers(),
            data={"query": "second question"},
        )
        assert second.status_code == 429, second.text
        error = second.json()["error"]
        assert error["status"] == 429
        assert error["uid"] == first_uid
    finally:
        _clear_deepsearch_jobs()
