#!/usr/bin/env bash
# Workflow(plan-review.js) 회수 후: l2.json 형식 검사 → 5.2d 예약 정산.
# 호출 전에 반환 봉투의 result 를 $STATE/l2.json 에 쓴다 (봉투째 쓰면 아래에서 result 를 꺼내 준다).
# exit 0 = 정산 완료 · 3 = l2.json 없음/형식 오류 (예약은 pin 된 채 남는다) · 12 = 5.2d 정지
set -euo pipefail
source "$(dirname "$0")/env.sh" "${1:-}"

L2="$STATE/l2.json"
if [ ! -s "$L2" ]; then
  echo "L2_STATE=absent"
  echo "l2.json 없음: 5.2d 를 하지 않는다. 예약은 debt marker 로 pin 된 채 남는다 (패널이 돌았을 수 있어 0 으로 세지 않는다)."
  exit 3
fi
# 봉투 {summary, logs, result, ...} 이면 result 를 꺼낸다. 그 밖의 형식은 거부한다.
set +e
SHAPE="$(node -e '
  const fs=require("fs"), p=process.argv[1];
  let j; try { j=JSON.parse(fs.readFileSync(p,"utf8")); } catch(e){ console.log("unparseable"); process.exit(0); }
  if (j && typeof j==="object" && !Array.isArray(j) && !("results" in j) && !("skipped" in j)
      && j.result && typeof j.result==="object") {
    j=j.result; fs.writeFileSync(p, JSON.stringify(j,null,2)); console.log("unwrapped");
  }
  const ok = j && typeof j==="object" && !Array.isArray(j)
    && (j.skipped===true || (Array.isArray(j.results) && j.reviewedPlanHash));
  console.log(ok ? (j.skipped===true?"skipped":"ok") : "bad-shape");
' "$L2")"
set -e
case "$SHAPE" in
  unwrapped*|ok|skipped) ;;
  bad-shape|unparseable)
    echo "L2_STATE=bad-shape"
    echo "l2.json 형식 오류 ($SHAPE). results 배열과 reviewedPlanHash 가 있어야 한다. 인자를 문자열로 넘겼으면(메모 1) 객체로 다시 넘긴다."
    exit 3 ;;
esac
[ "$SHAPE" = unwrapped ] && echo "[gatekit] l2.json 이 봉투였다 — result 를 꺼내 저장했다." >&2
SKIPPED="$(jread "$L2" 'j.skipped===true?1:0' 0)"
COVERAGE="$(jread "$L2" 'j.coverage' 0)"

# 5.2d 정산. 예약 id 와 발사 수는 아티팩트에서 읽는다 (셸 변수는 블록을 넘지 못한다).
RES_ID="$(jread "$STATE/reservation.json" 'j.reservationId' "")"
ACTUAL_N="$(jread "$STATE/workflow-args.json" 'j.fleet.length' "")"
if [ -z "$RES_ID" ] || [ -z "$ACTUAL_N" ]; then
  record_stop 5.2d
  echo "HALT_STAGE=5.2d"
  echo "예약 또는 fleet 아티팩트를 읽을 수 없다. 정산 불가 (임의 수치를 넣지 않는다)."
  exit 12
fi
if [ "$SKIPPED" = 1 ]; then
  ACTUAL_N=0
  echo "[gatekit] 패널 skip (에이전트 미발사) — --actual 0 으로 정산한다." >&2
fi
if ! node "$RUNAWAY" reconcile --reservation "$RES_ID" --actual "$ACTUAL_N" >/dev/null 2>&1; then
  echo "[gatekit] WARNING: reconcile 실패 — 예약 $RES_ID 는 pin 된 채 남는다 (over-count 방향으로 보수적)." >&2
fi
echo "L2_STATE=ok skipped=$SKIPPED coverage=$COVERAGE actual=$ACTUAL_N"
echo "NEXT=$( [ "$(jread "$STATE/mode.json" 'j.fires&&j.fires.l3?1:0' 0)" = 1 ] \
  && echo "hybrid: l3-run.sh $GK_N 를 Bash run_in_background 으로 띄우고 l3-poll.sh $GK_N 를 still-running 이 아닐 때까지 부른 뒤 post-b.sh $GK_N" \
  || echo "post-b.sh $GK_N" )"
