"""P2-3: A/B 분석 스크립트 단위 테스트."""

import json
import os
import sys
import tempfile
from pathlib import Path

_WORKSPACE = Path(os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace"))
sys.path.insert(0, str(_WORKSPACE))
sys.path.insert(0, str(_WORKSPACE / "scripts"))

import pytest


def _make_results(haiku_n=100, sonnet_n=100, haiku_fnr=0.05, sonnet_fnr=0.08):
    """테스트용 결과 데이터 생성."""
    results = []
    for i in range(haiku_n):
        results.append(
            {
                "request_id": f"h-{i}",
                "assigned_model": "haiku",
                "task_level": f"Lv.{(i % 3) + 1}",
                "fnr": haiku_fnr,
                "is_recheck": False,
                "timestamp": "2026-04-01T00:00:00+09:00",
            }
        )
    for i in range(sonnet_n):
        results.append(
            {
                "request_id": f"s-{i}",
                "assigned_model": "sonnet",
                "task_level": f"Lv.{(i % 3) + 1}",
                "fnr": sonnet_fnr,
                "is_recheck": False,
                "timestamp": "2026-04-01T00:00:00+09:00",
            }
        )
    return results


def _write_jsonl(data, path):
    with open(path, "w", encoding="utf-8") as f:
        for item in data:
            f.write(json.dumps(item, ensure_ascii=False) + "\n")


def test_load_results():
    """JSONL 파일 로드 테스트."""
    from analyze_ab import load_results

    with tempfile.NamedTemporaryFile(mode="w", suffix=".jsonl", delete=False) as f:
        f.write('{"request_id": "test-1", "assigned_model": "haiku"}\n')
        f.write('{"request_id": "test-2", "assigned_model": "sonnet"}\n')
        f.write("\n")
        path = f.name

    results = load_results(path)
    os.unlink(path)
    assert len(results) == 2


def test_compute_fnr():
    """FNR 계산 테스트."""
    from analyze_ab import compute_fnr

    results = _make_results(haiku_n=10, sonnet_n=10, haiku_fnr=0.1, sonnet_fnr=0.2)
    fnr, n = compute_fnr(results, "haiku")
    assert abs(fnr - 0.1) < 0.001
    assert n == 10


def test_verdict_adopt():
    """채택 판정 테스트: FNR < 15% AND p < 0.05."""
    from analyze_ab import determine_verdict

    v = determine_verdict(haiku_fnr=0.05, p_value=0.01, haiku_n=200, sonnet_n=200)
    assert v["verdict"] == "ADOPT"


def test_verdict_reject():
    """기각 판정 테스트: FNR >= 15%."""
    from analyze_ab import determine_verdict

    v = determine_verdict(haiku_fnr=0.20, p_value=0.01, haiku_n=200, sonnet_n=200)
    assert v["verdict"] == "REJECT"


def test_verdict_extend():
    """연장 판정 테스트: n <= 150."""
    from analyze_ab import determine_verdict

    v = determine_verdict(haiku_fnr=0.05, p_value=0.01, haiku_n=50, sonnet_n=50)
    assert v["verdict"] == "EXTEND"


def test_stratification_check():
    """층화 추출 균등 분배 검증."""
    from analyze_ab import stratification_check

    results = _make_results(haiku_n=300, sonnet_n=300)
    strat = stratification_check(results)
    for level, info in strat.items():
        assert info["balanced"], f"{level} 불균형: haiku {info['haiku_pct']}%"


def test_ab_results_jsonl_schema():
    """logs/ab_results.jsonl 스키마 유효성 검사."""
    jsonl_path = str(_WORKSPACE / "logs" / "ab_results.jsonl")
    if not os.path.exists(jsonl_path):
        pytest.skip("ab_results.jsonl 미존재")

    required_fields = {"request_id", "assigned_model", "task_level", "fnr", "is_recheck", "timestamp"}
    with open(jsonl_path, "r", encoding="utf-8") as f:
        for line_num, line in enumerate(f, 1):
            line = line.strip()
            if not line:
                continue
            record = json.loads(line)
            missing = required_fields - set(record.keys())
            assert not missing, f"Line {line_num}: 필수 필드 누락: {missing}"


def test_fishers_exact_mock():
    """Fisher's exact test 계산 결과 검증 (목 데이터)."""
    from analyze_ab import fishers_exact_test

    results = _make_results(haiku_n=200, sonnet_n=200, haiku_fnr=0.05, sonnet_fnr=0.08)
    result = fishers_exact_test(results)
    if "error" in result and "scipy" in str(result.get("error", "")):
        pytest.skip("scipy 미설치")
    assert "p_value" in result
    assert isinstance(result["p_value"], float)
