#!/usr/bin/env bash
# P1 gate. Replays Mike's flow chart end to end against the live deployment and
# asserts the audit trail can answer for every step.
#
#   report -> triage -> schedule -> in progress -> parts used -> parts returned
#   -> close -> spawn a follow-up linked to the parent
#
# Usage: main/scripts/gate-p1.sh
set -uo pipefail

BASE="${CP_BASE:-http://172.17.0.1:3140}"
DB_CONTAINER="${CP_DB_CONTAINER:-coachpapa-db}"

pass=0
fail=0
ok()  { printf '  PASS  %s\n' "$1"; pass=$((pass + 1)); }
bad() { printf '  FAIL  %s\n' "$1"; fail=$((fail + 1)); }
check() { if [ "$2" = "$3" ]; then ok "$1"; else bad "$1 (expected '$3', got '$2')"; fi; }
jqf() { python3 -c "import sys,json;d=json.load(sys.stdin);print($1)"; }

echo "P1 gate -> $BASE"

planner="$(curl -s --max-time 10 "$BASE/api/technicians" \
  | jqf "[t['id'] for t in d if t['role']=='planner'][0]")"
tech="$(curl -s --max-time 10 "$BASE/api/technicians" \
  | jqf "[t['id'] for t in d if t['role']=='tech'][0]")"
asset="$(curl -s --max-time 10 "$BASE/api/assets?q=conveyor&limit=1" | jqf "d[0]['id']")"
part="$(curl -s --max-time 10 "$BASE/api/parts?q=belt&limit=1" | jqf "d[0]['id']")"

patch() {
  curl -s --max-time 15 -X PATCH "$BASE/api/tickets/$1" \
    -H "X-CP-Actor: $2" -H 'Content-Type: application/json' -d "$3"
}

# --- 1. report --------------------------------------------------------------
ticket="$(curl -s --max-time 20 -X POST "$BASE/api/tickets" \
  -H "X-CP-Actor: $tech" \
  -F "payload={\"description\":\"gate-p1 outfeed bearing shrieking\",\"asset_id\":$asset,\"priority\":\"high\"}")"
tid="$(printf '%s' "$ticket" | jqf "d['id']")"
tnum="$(printf '%s' "$ticket" | jqf "d['display_number']")"
[ -n "$tid" ] && ok "ticket reported ($tnum)" || bad "ticket reported"

# --- 2-4. planner moves it along -------------------------------------------
check "triaged"     "$(patch "$tid" "$planner" '{"status":"triaged"}'     | jqf "d['status']")" "triaged"
check "scheduled"   "$(patch "$tid" "$planner" '{"status":"scheduled"}'   | jqf "d['status']")" "scheduled"
check "in progress" "$(patch "$tid" "$tech"    '{"status":"in_progress"}' | jqf "d['status']")" "in_progress"

# --- 5. parts used, then some returned to stock -----------------------------
usage() {
  curl -s --max-time 15 -X POST "$BASE/api/tickets/$tid/parts" \
    -H "X-CP-Actor: $tech" -H 'Content-Type: application/json' \
    -d "{\"part_id\":$part,\"quantity\":$1,\"direction\":\"$2\"}"
}
usage 8 used >/dev/null
returned="$(usage 3 returned)"
check "parts used and returned are both recorded" \
  "$(printf '%s' "$returned" | jqf "len(d['parts_used'])")" "2"

# --- 6. close ---------------------------------------------------------------
closed="$(patch "$tid" "$tech" '{"status":"closed"}')"
check "closed" "$(printf '%s' "$closed" | jqf "d['status']")" "closed"
closed_at="$(printf '%s' "$closed" | jqf "d['closed_at'] is not None")"
check "closing stamps closed_at" "$closed_at" "True"

# --- 7. follow-up linked to its parent --------------------------------------
child="$(curl -s --max-time 20 -X POST "$BASE/api/tickets" \
  -H "X-CP-Actor: $tech" \
  -F "payload={\"description\":\"gate-p1 right hand wear strip needs replacement\",\"asset_id\":$asset,\"priority\":\"normal\",\"parent_ticket_id\":$tid}")"
cid="$(printf '%s' "$child" | jqf "d['id']")"
check "follow-up records its parent" \
  "$(printf '%s' "$child" | jqf "d['parent_display_number']")" "$tnum"

parent_after="$(curl -s --max-time 10 "$BASE/api/tickets/$tid")"
check "parent's history names the follow-up" \
  "$(printf '%s' "$parent_after" | jqf "any(e['kind']=='follow_up_raised' for e in d['events'])")" \
  "True"

# --- 8. the audit trail can answer for every step ---------------------------
kinds="$(printf '%s' "$parent_after" | jqf "','.join(e['kind'] for e in d['events'])")"
for expected in reported status_changed part_used part_returned follow_up_raised; do
  case "$kinds" in
    *"$expected"*) ok "audit trail contains '$expected'" ;;
    *) bad "audit trail contains '$expected' (got: $kinds)" ;;
  esac
done

unattributed="$(printf '%s' "$parent_after" | jqf "sum(1 for e in d['events'] if not e['actor_name'])")"
check "every audit entry is attributed" "$unattributed" "0"
untimed="$(printf '%s' "$parent_after" | jqf "sum(1 for e in d['events'] if not e['at'])")"
check "every audit entry is timestamped" "$untimed" "0"

# --- cleanup: void the gate's tickets, numbers stay consumed ----------------
for id in "$tid" "$cid"; do
  [ -n "$id" ] && patch "$id" "$planner" '{"status":"void"}' >/dev/null
done

echo
echo "P1 gate: $pass passed, $fail failed"
[ "$fail" -eq 0 ] || exit 1
