#!/bin/bash
# before_exit_guard_hook.sh — task-2712 FAILURE_CALLBACK_BEFORE_EXIT_GUARD
#
# finish-task.sh 가 source 하는 bash hook. 9 terminal state + CRASH_NO_EXIT_CODE
# 어떤 exit point 에서든 exit 전에 disk terminal marker 박제를 보장한다.
#
# 회장 verbatim doctrine (task-2712 §3.1.2 / §5.1): callback = mandatory
# lifecycle signal for ALL terminal states. .done 은 SUCCESS 전용이며 본 hook
# 은 failure terminal state 의 marker 박제만 담당한다 (exactly-one rule 은
# failure_envelope_writer.write_envelope 가 보장 — .done 존재 시 no-op).
#
# 사용법 (source 후):
#   _emit_failure_envelope <terminal_state> <task_id> <exit_code> <failure_kind> [marker_type] [phase]
#
# 예:
#   _emit_failure_envelope SCOPE_GUARD_FAIL "$TASK_ID" "$exit_code" "scope_violation_count_61"
#
# trap 등록 (finish-task.sh 에서):
#   trap '_emit_failure_envelope CRASH_NO_EXIT_CODE "$TASK_ID" $? "trap_EXIT" supervisor_crash; cleanup_timer' EXIT
#   trap '_emit_failure_envelope CRASH_NO_EXIT_CODE "$TASK_ID" -2 "SIGINT" supervisor_crash' INT
#   trap '_emit_failure_envelope CRASH_NO_EXIT_CODE "$TASK_ID" -15 "SIGTERM" supervisor_crash' TERM

# 멱등 source 가드
if [ -n "${_BEFORE_EXIT_GUARD_HOOK_2712_LOADED:-}" ]; then
    return 0 2>/dev/null || true
fi
_BEFORE_EXIT_GUARD_HOOK_2712_LOADED=1

_FCB2712_WORKSPACE="${WORKSPACE:-/home/jay/workspace}"
_FCB2712_EVENTS_DIR="${EVENTS_DIR:-$_FCB2712_WORKSPACE/memory/events}"
_FCB2712_WRITER="$_FCB2712_WORKSPACE/scripts/harness/v36/failure_envelope_writer.py"

# _emit_failure_envelope: exit 전 terminal marker 박제 (best-effort · 비차단)
# 인자: $1=terminal_state $2=task_id $3=exit_code $4=failure_kind
#       $5=marker_type(선택, 기본 failure_envelope) $6=phase(선택)
_emit_failure_envelope() {
    local terminal_state="$1"
    local task_id="$2"
    local exit_code="${3:-1}"
    local failure_kind="${4:-}"
    local marker_type="${5:-failure_envelope}"
    local phase="${6:-${FCB2712_PHASE:-}}"

    [ -z "$task_id" ] && return 0

    # task-2712 Gemini MEDIUM #3: events dir 부재 시 redirect/append 실패 → python
    # 미실행(marker 미박제) 방지. 어떤 file 연산/redirect 보다 먼저 dir 보장 (비차단).
    mkdir -p "$_FCB2712_EVENTS_DIR" 2>/dev/null || true

    # SUCCESS / .done 이미 존재 시 no-op (exactly-one rule · python 측에서도 가드)
    if [ "$terminal_state" = "SUCCESS" ] || [ -f "$_FCB2712_EVENTS_DIR/${task_id}.done" ]; then
        return 0
    fi

    # 이미 failure terminal marker 가 있으면 multi-fire 방지 (no-op)
    if [ -f "$_FCB2712_EVENTS_DIR/${task_id}.failure-envelope.json" ] \
        || [ -f "$_FCB2712_EVENTS_DIR/${task_id}.failure-handoff-marker.json" ] \
        || [ -f "$_FCB2712_EVENTS_DIR/${task_id}.supervisor-crash-marker.json" ]; then
        return 0
    fi

    if [ ! -f "$_FCB2712_WRITER" ]; then
        # writer 부재 시 stderr 1-line fallback (§4.3)
        echo "FAILURE_CALLBACK_2712 task_id=${task_id} terminal_state=${terminal_state} exit_code=${exit_code} failure_kind=${failure_kind} phase=${phase}" >&2
        echo "FAILURE_CALLBACK_2712 task_id=${task_id} terminal_state=${terminal_state} exit_code=${exit_code} failure_kind=${failure_kind} phase=${phase}" \
            >> "$_FCB2712_EVENTS_DIR/${task_id}.stderr-emit.log" 2>/dev/null || true
        return 0
    fi

    FAILURE_CALLBACK_2712_EVENTS_DIR="$_FCB2712_EVENTS_DIR" \
        python3 "$_FCB2712_WRITER" \
        --task-id "$task_id" \
        --terminal-state "$terminal_state" \
        --exit-code "$exit_code" \
        --failure-kind "$failure_kind" \
        --phase "$phase" \
        --marker-type "$marker_type" \
        --events-dir "$_FCB2712_EVENTS_DIR" 2>>"$_FCB2712_EVENTS_DIR/${task_id}.stderr-emit.log" \
        || {
            # python 자체 실패 시 stderr 1-line last-resort
            echo "FAILURE_CALLBACK_2712 task_id=${task_id} terminal_state=${terminal_state} exit_code=${exit_code} failure_kind=${failure_kind} phase=${phase}" >&2
            echo "FAILURE_CALLBACK_2712 task_id=${task_id} terminal_state=${terminal_state} exit_code=${exit_code} failure_kind=${failure_kind} phase=${phase}" \
                >> "$_FCB2712_EVENTS_DIR/${task_id}.stderr-emit.log" 2>/dev/null || true
        }
    # §4.3.1 retention: 비어있는 stderr-emit.log 는 삭제 (false fallback evidence 방지)
    if [ -f "$_FCB2712_EVENTS_DIR/${task_id}.stderr-emit.log" ] \
        && [ ! -s "$_FCB2712_EVENTS_DIR/${task_id}.stderr-emit.log" ]; then
        rm -f "$_FCB2712_EVENTS_DIR/${task_id}.stderr-emit.log"
    fi
    return 0
}
