# grantflow/tests/test_integration_generation_preflight.py

from fastapi.testclient import TestClient

import grantflow.api.routes.jobs as jobs_routes
from grantflow.api import runtime_state
from grantflow.api.app import app
from grantflow.core.config import config
from grantflow.tests.integration_helpers import wait_for_terminal_status

client = TestClient(app)


def test_generate_response_and_status_include_preflight_payload():
    runtime_state.INGEST_AUDIT_STORE.clear()

    response = client.post(
        "/generate",
        json={
            "donor_id": "usaid",
            "input_context": {"project": "Water Sanitation", "country": "Kenya"},
            "llm_mode": False,
            "hitl_enabled": False,
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert data["status"] == "accepted"
    preflight = data.get("preflight")
    assert isinstance(preflight, dict)
    assert preflight["donor_id"] == "usaid"
    assert preflight["architect_rag_enabled"] is True
    assert preflight["risk_level"] == "high"
    assert preflight["grounding_risk_level"] == "high"
    assert isinstance(preflight.get("grounding_policy"), dict)

    status = wait_for_terminal_status(client, data["job_id"])
    assert status["generate_preflight"] == preflight
    assert status["state"]["generate_preflight"] == preflight
    assert status["state"]["architect_rag_enabled"] is True
    assert status["strict_preflight"] is False
    assert status["state"]["strict_preflight"] is False


def test_generate_respects_architect_rag_enabled_flag():
    runtime_state.INGEST_AUDIT_STORE.clear()

    response = client.post(
        "/generate",
        json={
            "donor_id": "usaid",
            "input_context": {"project": "Water Sanitation", "country": "Kenya"},
            "llm_mode": False,
            "architect_rag_enabled": False,
            "hitl_enabled": False,
        },
    )
    assert response.status_code == 200
    data = response.json()
    assert data["preflight"]["architect_rag_enabled"] is False
    job_id = data["job_id"]

    status = wait_for_terminal_status(client, job_id)
    assert status["state"]["architect_rag_enabled"] is False


def test_generate_strict_preflight_blocks_when_risk_is_high():
    runtime_state.INGEST_AUDIT_STORE.clear()

    response = client.post(
        "/generate",
        json={
            "donor_id": "usaid",
            "input_context": {"project": "Water Sanitation", "country": "Kenya"},
            "llm_mode": False,
            "hitl_enabled": False,
            "strict_preflight": True,
        },
    )
    assert response.status_code == 409
    detail = response.json()["detail"]
    assert detail["reason"] == "preflight_high_risk_block"
    assert detail["preflight"]["risk_level"] == "high"
    assert detail["preflight"]["grounding_risk_level"] == "high"
    assert "strict_reasons" in detail
    assert detail["preflight"]["go_ahead"] is False


def test_generate_strict_preflight_allows_when_risk_is_not_high(monkeypatch):
    monkeypatch.setattr(
        jobs_routes,
        "_build_generate_preflight",
        lambda donor_id, strategy, client_metadata, **kwargs: {
            "donor_id": donor_id,
            "risk_level": "medium",
            "go_ahead": True,
            "warning_count": 1,
            "retrieval_namespace": "usaid_ads201",
            "namespace_empty": False,
            "warnings": [{"code": "LOW_DOC_COVERAGE", "severity": "medium"}],
        },
    )
    response = client.post(
        "/generate",
        json={
            "donor_id": "usaid",
            "input_context": {"project": "Water Sanitation", "country": "Kenya"},
            "llm_mode": False,
            "hitl_enabled": False,
            "strict_preflight": True,
        },
    )
    assert response.status_code == 200
    assert response.json()["status"] == "accepted"


def test_generate_strict_preflight_blocks_when_grounding_risk_is_high(monkeypatch):
    monkeypatch.setattr(
        jobs_routes,
        "_build_generate_preflight",
        lambda donor_id, strategy, client_metadata, **kwargs: {
            "donor_id": donor_id,
            "risk_level": "medium",
            "grounding_risk_level": "high",
            "go_ahead": True,
            "warning_count": 1,
            "retrieval_namespace": "usaid_ads201",
            "namespace_empty": False,
            "warnings": [{"code": "LOW_DOC_COVERAGE", "severity": "medium"}],
            "grounding_policy": {
                "mode": "warn",
                "risk_level": "high",
                "blocking": False,
                "go_ahead": True,
                "summary": "namespace_empty_or_low_coverage",
                "reasons": ["coverage_below_50pct"],
            },
        },
    )
    response = client.post(
        "/generate",
        json={
            "donor_id": "usaid",
            "input_context": {"project": "Water Sanitation", "country": "Kenya"},
            "llm_mode": False,
            "hitl_enabled": False,
            "strict_preflight": True,
        },
    )
    assert response.status_code == 409
    detail = response.json()["detail"]
    assert detail["reason"] == "preflight_high_risk_block"
    assert "grounding_risk_high" in (detail.get("strict_reasons") or [])
    assert detail["preflight"]["risk_level"] == "medium"
    assert detail["preflight"]["grounding_risk_level"] == "high"


def test_generate_require_grounded_generation_blocks_llm_when_grounding_risk_is_high(monkeypatch):
    monkeypatch.setattr(
        jobs_routes,
        "_build_generate_preflight",
        lambda donor_id, strategy, client_metadata, **kwargs: {
            "donor_id": donor_id,
            "risk_level": "medium",
            "grounding_risk_level": "high",
            "go_ahead": True,
            "warning_count": 1,
            "retrieval_namespace": "usaid_ads201",
            "namespace_empty": False,
            "warnings": [{"code": "LOW_DOC_COVERAGE", "severity": "medium"}],
            "grounding_policy": {
                "mode": "warn",
                "risk_level": "high",
                "blocking": False,
                "go_ahead": True,
                "summary": "namespace_empty_or_low_coverage",
                "reasons": ["coverage_below_50pct"],
            },
        },
    )
    response = client.post(
        "/generate",
        json={
            "donor_id": "usaid",
            "input_context": {"project": "Water Sanitation", "country": "Kenya"},
            "llm_mode": True,
            "require_grounded_generation": True,
            "hitl_enabled": False,
            "strict_preflight": False,
        },
    )
    assert response.status_code == 409
    detail = response.json()["detail"]
    assert detail["reason"] == "llm_grounded_generation_block"
    assert "grounding_risk_high" in (detail.get("strict_reasons") or [])
    assert detail["preflight"]["grounding_risk_level"] == "high"


def test_generate_blocks_when_preflight_grounding_policy_is_strict(monkeypatch):
    monkeypatch.setattr(config.graph, "grounding_gate_mode", "strict")
    monkeypatch.setattr(config.graph, "preflight_grounding_policy_mode", "strict")
    runtime_state.INGEST_AUDIT_STORE.clear()

    response = client.post(
        "/generate",
        json={
            "donor_id": "usaid",
            "input_context": {"project": "Water Sanitation", "country": "Kenya"},
            "llm_mode": False,
            "hitl_enabled": False,
            "strict_preflight": False,
        },
    )
    assert response.status_code == 409
    detail = response.json()["detail"]
    assert detail["reason"] == "preflight_grounding_policy_block"
    assert detail["preflight"]["grounding_policy"]["mode"] == "strict"
    assert detail["preflight"]["grounding_policy"]["blocking"] is True
    assert detail["preflight"]["go_ahead"] is False
