#!/usr/bin/env bash
# Verify that a tapestry cold-start + three tab cycles stays within the
# MAX_BACKFILL_PAGES=48 ceiling — the invariant ba57fc7 (§6.5) put in.
#
# Pre-fix measurement: 4247 page GETs in 30 min against a quiet instance
# across in-session tab re-entries. Post-fix: 48 page GETs for the full
# session (24 h eager backfill, never re-walks on tab return).
#
# This recipe wipes the RQ MMKV cache, deep-links into /tapestry,
# bounces home ↔ tapestry three times, and asserts the slice's total
# /tapestry/page count is ≤ 48.
#
# Prereqs: scripts/dev/tail-logs.sh running; iPhone sim booted.

set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
DEV="$REPO_ROOT/scripts/dev"
# shellcheck source=/dev/null
source "$DEV/sim.env"
cd "$REPO_ROOT"

SETTLE_S=10           # let the eager backfill finish before counting
TAB_SETTLE_S=2        # per-cycle dwell on each tab
FINAL_SETTLE_S=3      # capture any straggler page walks after the last switch
EXPECTED_MAX_WALKS=48

note() { echo "[verify:tapestry-cold-start] $*"; }
fail() { echo "✗ $*"; exit 1; }
pass() { echo "✓ $*"; }

# ---- Wipe + relaunch + nav ---------------------------------------------------
note "Wiping RQ MMKV + relaunching iPhone sim into /tapestry…"
"$DEV/relaunch-ios.sh" --wipe=rq --nav='/(auth)/tapestry' || fail "relaunch-ios failed"

# Settle: eager backfill on cold start walks 48 pages — give it room.
sleep "$SETTLE_S"

# ---- Mark the log slice ------------------------------------------------------
# Mark AFTER the cold-start backfill so the count we assert against is
# strictly the tab-switching activity, NOT the cold-start eager walk.
# (Spec §6.5: cold mount IS expected to do up to 48 walks; subsequent
# tab returns must do 0.)
note "Marking net.log @ post-cold-start (24h backfill should be complete)…"
"$DEV/since.sh" mark net >/dev/null

# ---- Three tab cycles --------------------------------------------------------
note "Cycling home ↔ tapestry three times…"
for i in 1 2 3; do
  xcrun simctl openurl $IPHONE_UDID 'halflight:///(auth)/(tabs)/' >/dev/null
  sleep "$TAB_SETTLE_S"
  xcrun simctl openurl $IPHONE_UDID 'halflight:///(auth)/tapestry' >/dev/null
  sleep "$TAB_SETTLE_S"
done
sleep "$FINAL_SETTLE_S"

# ---- Count + assert ----------------------------------------------------------
walks=$("$DEV/tapestry-stats.sh" --since --raw \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['page_walks_total'])" \
  2>/dev/null || echo 'ERR')

if [[ "$walks" == "ERR" ]]; then
  fail "could not parse tapestry-stats output"
fi

note "Tab-cycle page walks (post-cold-start): $walks (allowed: 0)"
if [[ "$walks" -ne 0 ]]; then
  fail "$walks tapestry/page walks across 3 tab cycles (expected 0 — cached pages should be reused)"
fi
pass "0 page walks across 3 tab cycles — staleTime:Infinity + 24h cap holding"

# Sanity: confirm the cold-start backfill itself stayed in budget. Reset
# the marker so we slice from session start and re-count.
echo 0 > "$REPO_ROOT/temp/dev-logs/latest/.markers/net"
cold=$("$DEV/tapestry-stats.sh" --since --raw \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['page_walks_total'])")

note "Cold-start eager backfill walks: $cold (cap: $EXPECTED_MAX_WALKS)"
if [[ "$cold" -gt "$EXPECTED_MAX_WALKS" ]]; then
  fail "cold-start walked $cold pages — MAX_BACKFILL_PAGES regression?"
fi
pass "cold-start ≤ $EXPECTED_MAX_WALKS pages — MAX_BACKFILL_PAGES holding"
