# tests/test_c8_submit_eval.py

import json

from veritell_langchain import VeritellEvaluator


def _ndjson_lines(objs):
    return "\n".join(json.dumps(o) for o in objs).encode("utf-8")


def test_c8_evaluate_strings_posts_to_evaluate_stream_and_sends_minimal_payload(monkeypatch):
    captured = {}

    def fake_post(*, url, payload, headers, timeout, stream):
        captured["url"] = url
        captured["payload"] = payload
        captured["headers"] = headers
        captured["timeout"] = timeout
        captured["stream"] = stream

        class _Resp:
            status_code = 200

            def iter_lines(self):
                yield from _ndjson_lines(
                    [
                        {"type": "primary", "text": "primary-output"},
                        {
                            "type": "summary",
                            "schema_version": "2025-01-01",
                            "hallucination": 2,
                            "bias": 2,
                            "safety": 2,
                            "overall_risk": 10.0,
                            "risk_label": "low",
                        },
                        {"type": "done", "ok": True},
                    ]
                ).splitlines()

        return _Resp()

    monkeypatch.setattr("veritell_langchain.evaluator._post_ndjson", fake_post)

    ev = VeritellEvaluator(api_key="vk_test_secret", base_url="https://api.veritell.dev")
    res = ev.evaluate_strings(prediction="out", input="prompt")

    assert captured["url"] == "https://api.veritell.dev/evaluate/stream"
    assert captured["stream"] is True

    assert captured["payload"]["prompt"] == "prompt"
    assert captured["payload"]["model_output"] == "out"

    assert "api_key" not in captured["payload"]
    assert "Authorization" not in captured["payload"]
    assert "vk_test_secret" not in json.dumps(captured["payload"])

    assert captured["headers"]["Authorization"] == "Bearer vk_test_secret"
    assert res["risk_label"] == "low"


def test_c8_explicit_options_are_included_and_only_expected_keys_are_sent(monkeypatch):
    captured = {}

    def fake_post(*, url, payload, headers, timeout, stream):
        captured["payload"] = payload

        class _Resp:
            status_code = 200

            def iter_lines(self):
                yield from _ndjson_lines(
                    [
                        {
                            "type": "summary",
                            "schema_version": "2025-01-01",
                            "hallucination": 2,
                            "bias": 2,
                            "safety": 2,
                            "overall_risk": 10.0,
                            "risk_label": "low",
                        },
                        {"type": "done", "ok": True},
                    ]
                ).splitlines()

        return _Resp()

    monkeypatch.setattr("veritell_langchain.evaluator._post_ndjson", fake_post)

    ev = VeritellEvaluator(api_key="vk_test_secret", base_url="https://api.veritell.dev")
    ev.evaluate_strings(
        prediction="out",
        input="prompt",
        primary_model="gpt-4o",
        judges=["gpt-4o-mini"],
    )

    assert captured["payload"]["prompt"] == "prompt"
    assert captured["payload"]["model_output"] == "out"
    assert captured["payload"]["primary_model"] == "gpt-4o"
    assert captured["payload"]["judges"] == ["gpt-4o-mini"]
    assert set(captured["payload"].keys()) == {
        "prompt",
        "model_output",
        "primary_model",
        "judges",
    }


def test_c8_does_not_forward_extra_kwargs_or_langchain_state(monkeypatch):
    captured = {}

    def fake_post(*, url, payload, headers, timeout, stream):
        captured["payload"] = payload

        class _Resp:
            status_code = 200

            def iter_lines(self):
                yield from _ndjson_lines(
                    [
                        {
                            "type": "summary",
                            "schema_version": "2025-01-01",
                            "hallucination": 2,
                            "bias": 2,
                            "safety": 2,
                            "overall_risk": 10.0,
                            "risk_label": "low",
                        },
                        {"type": "done", "ok": True},
                    ]
                ).splitlines()

        return _Resp()

    monkeypatch.setattr("veritell_langchain.evaluator._post_ndjson", fake_post)

    ev = VeritellEvaluator(api_key="vk_test_secret", base_url="https://api.veritell.dev")

    ev.evaluate_strings(
        prediction="out",
        input="prompt",
        primary_model="gpt-4o",
        judges=["gpt-4o-mini"],
        metadata={"run_tree": object(), "secrets": {"VERITELL_API_KEY": "nope"}},
        callbacks=object(),
        run_manager=object(),
        tags=["t1"],
    )

    assert "metadata" not in captured["payload"]
    assert "callbacks" not in captured["payload"]
    assert "run_manager" not in captured["payload"]
    assert "tags" not in captured["payload"]
    assert "VERITELL_API_KEY" not in json.dumps(captured["payload"])
