"""Testet, dass die Zahl der Faktenaussagen mit dem Material waechst.

Laeuft ohne Netzzugriff und ohne Kosten, der Modellaufruf ist ersetzt.

Aufruf aus dem Projektstamm:
    venv/bin/python tests/test_faktenspanne.py
"""
import asyncio
import os
import sys

sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "src"))

import agents.factchecker as fcmod  # noqa: E402
import agents.claude_client as cc  # noqa: E402
from agents.factchecker import (  # noqa: E402
    FactCheckerAgent, faktenspanne, FACTCHECK_PROMPT_TEMPLATE,
    RESEARCH_FACTCHECK_PROMPT_TEMPLATE, INCREMENTAL_FACTCHECK_PROMPT_TEMPLATE,
    INCREMENTAL_RESEARCH_FACTCHECK_PROMPT_TEMPLATE, TRIAGE_PROMPT_TEMPLATE,
)
from agents.claude_client import _ai_backend_var, ClaudeUsage  # noqa: E402
from config import FAKTEN_MAX, FAKTEN_MIN, FAKTEN_NEU_MAX, FAKTEN_NEU_MIN  # noqa: E402

ok = 0
fail = 0


def pruefe(name, bedingung, extra=""):
    global ok, fail
    if bedingung:
        ok += 1
        print("  OK    " + name)
    else:
        fail += 1
        print("  FEHL  " + name + " " + str(extra))


print("\nA) Die Spanne waechst mit der Zahl der Meldungen")
klein = faktenspanne(16)
mittel = faktenspanne(53)
gross = faktenspanne(88)
sehr_gross = faktenspanne(300)
pruefe("A1 wenige Meldungen ergeben die alte Spanne", klein == (5, 10), klein)
pruefe("A2 mehr Meldungen ergeben mehr Fakten", gross[1] > klein[1], (klein, gross))
pruefe("A3 die Reihenfolge stimmt",
       klein[1] <= mittel[1] <= gross[1] <= sehr_gross[1],
       (klein, mittel, gross, sehr_gross))
pruefe("A4 Obergrenze wird eingehalten", sehr_gross[1] == FAKTEN_MAX, sehr_gross)
pruefe("A5 Untergrenze wird eingehalten", faktenspanne(0)[0] == FAKTEN_MIN, faktenspanne(0))
pruefe("A6 Untergrenze liegt nie ueber der Obergrenze",
       all(faktenspanne(n)[0] <= faktenspanne(n)[1] for n in range(0, 400, 7)))
pruefe("A7 negative Eingabe bricht nicht", faktenspanne(-5) == (5, 10), faktenspanne(-5))

print("\nB) Fuer die Aktualisierung gilt ein engerer Korridor")
neu_klein = faktenspanne(8, neu=True)
neu_gross = faktenspanne(200, neu=True)
pruefe("B1 wenige neue Meldungen ergeben die alte Spanne",
       neu_klein == (FAKTEN_NEU_MIN, FAKTEN_NEU_MIN * 2), neu_klein)
pruefe("B2 Obergrenze der Aktualisierung greift", neu_gross[1] == FAKTEN_NEU_MAX, neu_gross)
pruefe("B3 Aktualisierung bleibt unter der Erstpruefung",
       faktenspanne(200, neu=True)[1] < faktenspanne(200)[1])

print("\nC) Die Auftraege enthalten Platzhalter statt fester Zahlen")
for name, vorlage in (
        ("Erstpruefung adhoc", FACTCHECK_PROMPT_TEMPLATE),
        ("Erstpruefung Recherche", RESEARCH_FACTCHECK_PROMPT_TEMPLATE),
        ("Aktualisierung adhoc", INCREMENTAL_FACTCHECK_PROMPT_TEMPLATE),
        ("Aktualisierung Recherche", INCREMENTAL_RESEARCH_FACTCHECK_PROMPT_TEMPLATE),
        ("Triage", TRIAGE_PROMPT_TEMPLATE)):
    pruefe(f"C {name} nutzt den Richtwert",
           "{fakten_min}" in vorlage and "{fakten_max}" in vorlage)
    pruefe(f"C {name} ohne feste Vorgabe",
           "5-10" not in vorlage and "3-5 " not in vorlage and "(3-5" not in vorlage)

pruefe("C Richtwert ist ausdruecklich keine Zielvorgabe",
       "Richtwert und keine" in FACTCHECK_PROMPT_TEMPLATE
       and "Zielvorgabe" in FACTCHECK_PROMPT_TEMPLATE)
pruefe("C Abweichen nach oben und unten ist erlaubt",
       "weniger" in FACTCHECK_PROMPT_TEMPLATE and "mehr" in FACTCHECK_PROMPT_TEMPLATE)

print("\nD) Der berechnete Wert landet im Auftrag")
letzter = {"prompt": ""}


async def fake_call_claude(prompt, tools="WebSearch,WebFetch", model=None,
                           raw_text=False, timeout=None):
    letzter["prompt"] = prompt
    return "[]", ClaudeUsage(input_tokens=10, output_tokens=5, cost_usd=0.01)


fcmod.call_claude = fake_call_claude
cc.call_claude = fake_call_claude
_ai_backend_var.set("cli")
fc = FactCheckerAgent()


def meldungen(n):
    return [{"headline": f"Meldung {i}", "source": "tagesschau",
             "source_url": f"https://tagesschau.de/{i}", "content_original": "t"}
            for i in range(n)]


asyncio.run(fc.check("Lage", meldungen(16), "adhoc", "Deutsch"))
u, o = faktenspanne(16)
pruefe("D1 kleine Lage traegt ihren Richtwert",
       f"etwa {u} bis {o} Aussagen" in letzter["prompt"],
       [z for z in letzter["prompt"].splitlines() if "Richtwert" in z][:1])

asyncio.run(fc.check("Lage", meldungen(88), "adhoc", "Deutsch"))
u2, o2 = faktenspanne(88)
pruefe("D2 grosse Lage traegt einen groesseren Richtwert",
       f"etwa {u2} bis {o2} Aussagen" in letzter["prompt"] and o2 > o,
       [z for z in letzter["prompt"].splitlines() if "Richtwert" in z][:1])

asyncio.run(fc.check_incremental(
    "Lage", meldungen(30),
    [{"claim": "Ein bestehender Punkt", "status": "confirmed", "evidence": "e"}],
    "adhoc", "Deutsch"))
u3, o3 = faktenspanne(30, neu=True)
pruefe("D3 Aktualisierung nutzt den engeren Korridor",
       f"etwa\n   {u3} bis {o3}" in letzter["prompt"] or f"{u3} bis {o3}" in letzter["prompt"],
       [z for z in letzter["prompt"].splitlines() if "Richtwert" in z][:1])

print("\nErgebnis: " + str(ok) + " bestanden, " + str(fail) + " fehlgeschlagen")
sys.exit(1 if fail else 0)
