"""task-2543 회귀 — done event fallback priority + idempotent reconcile."""
from __future__ import annotations

import json
import sys
from pathlib import Path

_REPO_ROOT = str(Path(__file__).resolve().parents[2])
# 본 worktree(_REPO_ROOT)를 sys.path 최우선에 강제 — tests/conftest.py 가
# /home/jay/workspace 를 먼저 prepend 하여 우리 worktree 의 scripts/ 패키지가
# shadow 되는 사고 방지 (회장 §명시 격리).
while _REPO_ROOT in sys.path:
    sys.path.remove(_REPO_ROOT)
sys.path.insert(0, _REPO_ROOT)

from dashboard import helpers
import scripts.reconcile_task_timers_2543 as recon


# 1. done event 시각이 task-timers.json end_time보다 우선
def test_done_event_priority_over_timers_end_time(tmp_path):
    events_dir = tmp_path / "events"
    events_dir.mkdir()
    (events_dir / "task-X.done").write_text(json.dumps({
        "task_id": "task-X",
        "completed_at": "2026-05-09T12:00:00+09:00",
    }), encoding="utf-8")
    timers = {"task-X": {"end_time": "2026-05-08T01:00:00"}}
    result = helpers._resolve_end_time_priority(
        "task-X", events_dir=events_dir, timers=timers, fallback_to_mtime=False
    )
    assert result == "2026-05-09T12:00:00+09:00"


# 2. fallback_to_mtime=False 시 mtime 미사용 → None 반환
def test_mtime_fallback_disabled(tmp_path):
    events_dir = tmp_path / "events"
    events_dir.mkdir()
    # done event 없음, timers entry 없음
    result = helpers._resolve_end_time_priority(
        "task-NX", events_dir=events_dir, timers={}, fallback_to_mtime=False, mtime=1715000000.0
    )
    assert result is None


# 3. chat_id 격리: 다른 chat의 done event는 reconcile에서 silently skip
def test_reconcile_skips_other_chat(tmp_path):
    events_dir = tmp_path / "events"
    events_dir.mkdir()
    (events_dir / "task-OTHERCHAT.done").write_text(json.dumps({
        "task_id": "task-OTHERCHAT",
        "completed_at": "2026-05-08T12:00:00",
        "team_id": "dev1-team",
        "chat_id": "9999999",
    }), encoding="utf-8")
    timers_path = tmp_path / "task-timers.json"
    timers_path.write_text(json.dumps({"tasks": {}}), encoding="utf-8")
    result = recon.reconcile_from_done_events(
        timers_path=timers_path,
        events_dir=events_dir,
        chat_id_filter=6937032012,
        target_date_range=("2026-05-08", "2026-05-09"),
        dry_run=False,
    )
    assert result["skipped_other_chat"] >= 1
    assert "task-OTHERCHAT" not in result.get("tasks_added", [])


# 4. idempotent: 같은 입력으로 두 번 실행 → 두 번째 backfilled=0
def test_reconcile_idempotent(tmp_path):
    events_dir = tmp_path / "events"
    events_dir.mkdir()
    (events_dir / "task-Y.done").write_text(json.dumps({
        "task_id": "task-Y",
        "completed_at": "2026-05-08T12:00:00+09:00",
        "team_id": "dev2-team",
    }), encoding="utf-8")
    timers_path = tmp_path / "task-timers.json"
    timers_path.write_text(json.dumps({"tasks": {}}), encoding="utf-8")
    r1 = recon.reconcile_from_done_events(
        timers_path=timers_path, events_dir=events_dir, dry_run=False,
    )
    r2 = recon.reconcile_from_done_events(
        timers_path=timers_path, events_dir=events_dir, dry_run=False,
    )
    assert r1["backfilled"] == 1
    assert r2["backfilled"] == 0
    assert r2["skipped_existing"] >= 1


# 5. 5/8 entry 박제: done event 시각으로 task-timers.json end_time backfill
def test_backfill_2026_05_08(tmp_path):
    events_dir = tmp_path / "events"
    events_dir.mkdir()
    (events_dir / "task-A.done").write_text(json.dumps({
        "task_id": "task-A",
        "completed_at": "2026-05-08T09:30:45+09:00",
        "team_id": "dev1-team",
    }), encoding="utf-8")
    timers_path = tmp_path / "task-timers.json"
    timers_path.write_text(json.dumps({"tasks": {}}), encoding="utf-8")
    recon.reconcile_from_done_events(
        timers_path=timers_path, events_dir=events_dir, dry_run=False,
    )
    saved = json.loads(timers_path.read_text(encoding="utf-8"))
    entry = saved["tasks"]["task-A"]
    assert "2026-05-08" in str(entry["end_time"])
    assert entry["status"] == "completed"
    assert entry.get("team_id") == "dev1-team"


# 6. 5/9 entry 박제
def test_backfill_2026_05_09(tmp_path):
    events_dir = tmp_path / "events"
    events_dir.mkdir()
    (events_dir / "task-B.done").write_text(json.dumps({
        "task_id": "task-B",
        "end_time": "2026-05-09T14:32:00",
        "team": "dev3-team",
    }), encoding="utf-8")
    timers_path = tmp_path / "task-timers.json"
    timers_path.write_text(json.dumps({"tasks": {}}), encoding="utf-8")
    recon.reconcile_from_done_events(
        timers_path=timers_path, events_dir=events_dir, dry_run=False,
    )
    saved = json.loads(timers_path.read_text(encoding="utf-8"))
    entry = saved["tasks"]["task-B"]
    assert "2026-05-09" in str(entry["end_time"])
    assert entry["status"] == "completed"


# 7. token raw 0: reconcile이 추가하는 entry에 토큰/raw response 미노출
def test_reconcile_no_token_leakage(tmp_path):
    events_dir = tmp_path / "events"
    events_dir.mkdir()
    # done event 본문에 hypothetical 토큰 필드가 있어도 reconcile은 옮기지 않음
    (events_dir / "task-T.done").write_text(json.dumps({
        "task_id": "task-T",
        "completed_at": "2026-05-08T10:00:00+09:00",
        "team_id": "dev2-team",
        "raw_response": "this should never be persisted",
        "api_key": "sk-secret",
        "tokens": {"input": 100, "output": 200},
    }), encoding="utf-8")
    timers_path = tmp_path / "task-timers.json"
    timers_path.write_text(json.dumps({"tasks": {}}), encoding="utf-8")
    recon.reconcile_from_done_events(
        timers_path=timers_path, events_dir=events_dir, dry_run=False,
    )
    saved_text = timers_path.read_text(encoding="utf-8")
    assert "raw_response" not in saved_text
    assert "sk-secret" not in saved_text
    # 'tokens' 키도 옮기지 않음 (reconcile이 추가한 entry 한정 — 기존 token_usage는 무관)
    saved = json.loads(saved_text)
    entry = saved["tasks"]["task-T"]
    # task-T는 reconcile로 새로 추가된 entry이므로 token 관련 필드 없어야 함
    for forbidden in ("raw_response", "api_key", "tokens"):
        assert forbidden not in entry, f"{forbidden} should not appear in reconciled entry"
