"""Tests for RCA backend adapters."""

from __future__ import annotations

from pathlib import Path

from llmdebug import _json as json
from llmdebug.rca_backend import backend_name, get_rca_history, get_rca_status, persist_rca_record


def _record(
    attempt_id: str,
    *,
    session_id: str = "sess-a",
    state: str = "captured",
    updated_at: str = "2026-02-27T10:00:00Z",
) -> dict[str, object]:
    return {
        "attempt_id": attempt_id,
        "session_id": session_id,
        "updated_at": updated_at,
        "created_at": "2026-02-27T10:00:00Z",
        "failure_signature": "sig-a",
        "state": state,
        "evidence_refs": ["r1"],
    }


def test_backend_name_defaults_and_invalid(monkeypatch) -> None:
    monkeypatch.delenv("LLMDEBUG_RCA_BACKEND", raising=False)
    assert backend_name() == "sqlite"

    monkeypatch.setenv("LLMDEBUG_RCA_BACKEND", "not-real")
    assert backend_name() == "sqlite"


def test_jsonl_roundtrip_status_and_history(tmp_path: Path, monkeypatch) -> None:
    monkeypatch.setenv("LLMDEBUG_RCA_BACKEND", "jsonl")
    monkeypatch.setenv("LLMDEBUG_RCA_MAX_RECORDS", "2")

    out_dir = str(tmp_path)
    persist_rca_record(out_dir=out_dir, record=_record("a1", updated_at="2026-02-27T10:00:00Z"))
    persist_rca_record(out_dir=out_dir, record=_record("a2", updated_at="2026-02-27T10:01:00Z"))
    persist_rca_record(out_dir=out_dir, record=_record("a3", updated_at="2026-02-27T10:02:00Z"))

    status = get_rca_status(out_dir=out_dir, session_id="sess-a")
    assert status is not None
    assert status["attempt_id"] == "a3"

    history = get_rca_history(out_dir=out_dir, session_id="sess-a", limit=10)
    assert [entry["attempt_id"] for entry in history] == ["a3", "a2"]

    store = tmp_path / "rca_attempts.jsonl"
    lines = [line for line in store.read_text(encoding="utf-8").splitlines() if line.strip()]
    assert len(lines) == 2


def test_sqlite_migration_guard_skips_when_rows_exist(tmp_path: Path, monkeypatch) -> None:
    monkeypatch.setenv("LLMDEBUG_RCA_BACKEND", "sqlite")
    out_dir = str(tmp_path)

    persist_rca_record(out_dir=out_dir, record=_record("sql-1"))

    jsonl_path = tmp_path / "rca_attempts.jsonl"
    jsonl_path.write_text(json.dumps(_record("jsonl-1")) + "\n", encoding="utf-8")

    history = get_rca_history(out_dir=out_dir, session_id="sess-a", limit=10)
    assert history
    assert jsonl_path.exists()
    assert not Path(f"{jsonl_path}.bak").exists()


def test_sqlite_migration_filters_invalid_records_and_applies_retention(
    tmp_path: Path, monkeypatch
) -> None:
    monkeypatch.setenv("LLMDEBUG_RCA_BACKEND", "sqlite")
    monkeypatch.setenv("LLMDEBUG_RCA_MAX_RECORDS", "2")
    out_dir = str(tmp_path)
    jsonl_path = tmp_path / "rca_attempts.jsonl"
    rows = [
        _record("a1", updated_at="2026-02-27T10:00:00Z"),
        {**_record("bad", updated_at="2026-02-27T10:00:30Z"), "attempt_id": ""},
        _record("a2", updated_at="2026-02-27T10:01:00Z"),
        _record("a3", updated_at="2026-02-27T10:02:00Z"),
    ]
    jsonl_path.write_text("\n".join(json.dumps(row) for row in rows) + "\n", encoding="utf-8")

    history = get_rca_history(out_dir=out_dir, session_id="sess-a", limit=10)
    assert [entry["attempt_id"] for entry in history] == ["a3", "a2"]
    assert not jsonl_path.exists()
    assert Path(f"{jsonl_path}.bak").exists()
