"""NORMAL_CALLBACK_NOT_REGISTERED marker 회귀 테스트 (task-2694+1 MT-6).

emit/check API + atomic overwrite (idempotency) 검증.
"""

from __future__ import annotations

import json
import os

from utils.callback_registration_marker import (  # pyright: ignore[reportMissingImports]
    MARKER_KIND_NOT_REGISTERED,
    emit_not_registered_marker,
    has_not_registered_marker,
)


def test_emit_creates_marker_file(tmp_path):
    """emit_not_registered_marker → marker file 생성 + hold_for_chair=True 박제."""
    em = emit_not_registered_marker(
        task_id="task-marker-1",
        reason="test fail",
        sources_checked={"schedule_id": "PASS", "schedule_history": "FAIL"},
        events_dir=str(tmp_path),
    )
    assert em.emitted is True, f"emit failed: reason={em.reason}"
    assert os.path.exists(em.marker_path)
    with open(em.marker_path, "r", encoding="utf-8") as fp:
        payload = json.load(fp)
    assert payload["marker_kind"] == MARKER_KIND_NOT_REGISTERED
    assert payload["task_id"] == "task-marker-1"
    assert payload["hold_for_chair"] is True
    assert payload["verdict"] == "FAIL"
    # sources_checked passthrough
    assert payload["sources_checked"]["schedule_id"] == "PASS"
    assert payload["sources_checked"]["schedule_history"] == "FAIL"


def test_has_marker_returns_true_when_present(tmp_path):
    """marker 발행 후 has_not_registered_marker 는 True."""
    emit_not_registered_marker(
        task_id="task-check-1",
        reason="r",
        events_dir=str(tmp_path),
    )
    assert has_not_registered_marker("task-check-1", str(tmp_path)) is True


def test_has_marker_returns_false_when_absent(tmp_path):
    """marker 없는 task_id 에 대해선 False."""
    assert has_not_registered_marker("task-never", str(tmp_path)) is False


def test_emit_is_idempotent(tmp_path):
    """동일 task_id 에 대한 재발행 → 동일 경로 + reason overwrite 보장."""
    em1 = emit_not_registered_marker(
        task_id="task-idem", reason="r1", events_dir=str(tmp_path)
    )
    em2 = emit_not_registered_marker(
        task_id="task-idem", reason="r2", events_dir=str(tmp_path)
    )
    assert em1.marker_path == em2.marker_path
    with open(em2.marker_path, "r", encoding="utf-8") as fp:
        payload = json.load(fp)
    assert payload["reason"] == "r2"  # 최신 reason 으로 덮어쓰기 확인


def test_has_marker_false_on_corrupted_payload(tmp_path):
    """malformed JSON marker 는 fail-safe 로 False 반환 (indefinite block 방지)."""
    marker_dir = str(tmp_path)
    # 정상 발행 후 강제로 파일을 손상시킨다
    em = emit_not_registered_marker(
        task_id="task-corrupt", reason="r", events_dir=marker_dir
    )
    with open(em.marker_path, "w", encoding="utf-8") as fp:
        fp.write("this is not json {{{")
    assert has_not_registered_marker("task-corrupt", marker_dir) is False


def test_has_marker_false_when_hold_for_chair_disabled(tmp_path):
    """hold_for_chair=False 로 발행된 marker 는 check 가 False (gate 해제 상태)."""
    em = emit_not_registered_marker(
        task_id="task-released",
        reason="r",
        events_dir=str(tmp_path),
        hold_for_chair=False,
    )
    assert em.emitted is True
    assert has_not_registered_marker("task-released", str(tmp_path)) is False
