"""CLI — Opik 역추적 프롬프트 감사.

backend/.env 의 OPIK_URL_OVERRIDE/OPIK_WORKSPACE/OPIK_PROJECT_NAME 을 그대로
읽는다 (backend 설정이 SOT).
"""
import argparse
import logging
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent.parent  # 저장소 루트
sys.path.insert(0, str(ROOT / "backend"))
sys.path.insert(0, str(ROOT))

logging.basicConfig(level=logging.INFO, format="%(message)s")


def main() -> None:
    ap = argparse.ArgumentParser(description="Opik 프롬프트 감사")
    ap.add_argument("--since", required=True,
                    help="ISO 시작 시각 (예: 2026-08-14T18:33:00)")
    ap.add_argument("--until", default="9999")
    ap.add_argument("--out", default=None,
                    help="출력 디렉토리 (기본: artifact/<날짜>_opik_prompt_audit)")
    args = ap.parse_args()

    import os
    os.chdir(ROOT / "backend")  # pydantic-settings 가 .env 를 cwd 에서 찾는다
    from app.core.config import settings

    base_url = (settings.opik_url_override or "").rstrip("/")
    if not base_url:
        raise SystemExit("OPIK_URL_OVERRIDE 가 비어 있다 — 셀프 호스팅 전용 도구")

    from tools.opik_prompt_audit.audit.attribute import (
        attribute_lines, build_line_index, growth_curves,
    )
    from tools.opik_prompt_audit.audit.fetch import (
        fetch_spans, fetch_trace_index, select_call_rows, test_filter_caveat,
    )
    from tools.opik_prompt_audit.audit.metrics import (
        cross_step_duplicates, per_step,
    )
    from tools.opik_prompt_audit.audit.report import render

    # ★세는 것은 **언제나 span** 이다 (2026-08-24). v1 호출 한 건은
    #   trace 1 + span 1 로 남아 있어서, 둘을 합치면 지난 자료가 두 배가 된다.
    #   trace 는 묶음·이름·시험 판별에만 쓴다.
    trace_index = fetch_trace_index(
        base_url, settings.opik_workspace, settings.opik_project_name,
        args.since, args.until)
    raw_rows = fetch_spans(base_url, settings.opik_workspace,
                           settings.opik_project_name, args.since, args.until)
    rows = select_call_rows(raw_rows, trace_index)
    steps = per_step(rows, trace_index)
    dups = cross_step_duplicates(steps)

    prompts_root = ROOT / "prompts"
    curves = growth_curves(prompts_root)
    index = build_line_index(prompts_root)
    attributions = {
        step: attribute_lines(
            [line for line, _df in
             (r.get("system_static_lines") or [])
             + (r.get("user_static_lines") or [])], index)
        for step, r in steps.items()
    }

    from datetime import datetime
    out_dir = Path(args.out) if args.out else (
        ROOT / "artifact"
        / f"{datetime.now():%Y%m%d}_opik_prompt_audit")
    out = render(
        out_dir,
        {"since": args.since, "call_count": len(rows),
         # ★몇 건을 뺐는지도 함께 싣는다 — 선택 목록만 넘기면 그 수가
         #   유실되어 리포트가 「걸러진 것이 없다」처럼 읽힌다.
         "raw_count": len(raw_rows),
         "excluded_test_rows": len(raw_rows) - len(rows),
         # 구 JSON 을 읽는 것이 있으면 이 별칭으로 찾는다.
         "trace_count": len(rows),
         "caveat": test_filter_caveat()},
        steps, dups, curves, attributions)
    print(f"리포트: {out}")


if __name__ == "__main__":
    main()
