#!/usr/bin/env bash
# PR #27827 (fix(client-runtime): new threads no longer stay blank when opened before they exist)
# Claim: already-fixed by #25919 (de21fbcff3): after a 404 snapshot miss, a mounted thread asks HTTP again with
# backoff (250 ms doubling) and subscribes once the thread exists. A maintainer closed linked issue #31681 as fixed by it.
# Behavioral proof: the PR's own test, taken verbatim from its head plus its two harness additions, passes on
# de21fbcff3 and fails on its parent, where a miss parks the subscription for good.
# Needs deps installed (`vp i`) and `gh` authenticated. Run from the root of a clean t3code checkout.
set -euo pipefail

REPO=pingdotgg/t3code
SUPER=de21fbcff3f0bd50058030d973c31c4255141c9e
TEST=packages/client-runtime/src/state/threads-sync.test.ts
PATTERN="loads a new thread whose first snapshot request ran before it existed|retains a deletion instead of restoring the old disk snapshot"
ok=1
pass() { echo "PASS  $*"; }
fail() { echo "FAIL  $*"; ok=0; }

if [ -n "$(git status --porcelain)" ]; then
  echo "refusing to run on a dirty tree"
  exit 2
fi
ORIG=$(git symbolic-ref -q --short HEAD || git rev-parse HEAD)
WORK=$(mktemp -d)
cleanup() {
  git checkout -q -f -- . 2>/dev/null || true
  git checkout -q -f "$ORIG" 2>/dev/null || true
  rm -rf "$WORK"
}
trap 'rc=$?; cleanup; [ "${PROOF_DONE:-0}" = 1 ] && exit 0; [ "$rc" -ne 0 ] && exit "$rc"; exit 1' EXIT

git fetch -q origin main
MAIN=$(git rev-parse FETCH_HEAD)
git fetch -q origin pull/27827/head
PR_HEAD=$(git rev-parse FETCH_HEAD)
git cat-file -e "$SUPER^{commit}"
PARENT=$(git rev-parse "$SUPER^")
echo "main=$MAIN pr_head=$PR_HEAD superseding=$SUPER parent=$PARENT"

# 1. Provenance: #25919 is on main, and the maintainer tied the linked issue to it.
subject=$(git log -1 --format=%s "$SUPER")
if git merge-base --is-ancestor "$SUPER" "$MAIN" && [[ "$subject" == *"(#25919)" ]]; then
  pass "#25919 is on main as $(git rev-parse --short "$SUPER") $subject"
else
  fail "$SUPER is not #25919 on main"
fi
issue=$(gh api "repos/$REPO/issues/31681" --jq '"\(.state) \(.state_reason) \(.closed_by.login)"')
if [ "$issue" = "closed completed juliusmarminge" ]; then
  pass "linked issue #31681 is closed as completed by juliusmarminge"
else
  fail "issue #31681 state/closer is '$issue'"
fi
fixed_by=$(gh api "repos/$REPO/issues/31681/comments" --jq '[.[] | select(.user.login == "juliusmarminge") | .body | select(startswith("Fixed by #25919"))] | length')
if [ "$fixed_by" -ge 1 ]; then
  pass "the maintainer's closing comment on #31681 says 'Fixed by #25919'"
else
  fail "no 'Fixed by #25919' comment from the maintainer on #31681"
fi

# 2. The PR's test, extracted verbatim from its head, with the PR's harness additions
#    (a mutable HTTP snapshot result and a queue of load calls) applied by anchor.
git show "$PR_HEAD:$TEST" > "$WORK/pr-test.ts"
cat > "$WORK/overlay.mjs" <<'EOF'
import { readFileSync, writeFileSync } from "node:fs";
const [target, prFile, advance] = process.argv.slice(2);
let src = readFileSync(target, "utf8");
const pr = readFileSync(prFile, "utf8");
const must = (cond, what) => { if (!cond) { console.error(`overlay: missing ${what}`); process.exit(3); } };
const start = pr.indexOf('  it.effect.each(["same session", "replaced session"] as const)(');
const end = pr.indexOf('  it.effect("does not recreate a deleted cache from a queued save or finalizer"', start);
must(start >= 0 && end > start, "the PR's test block");
let block = pr.slice(start, end);
if (advance) {
  must(block.includes('TestClock.adjust("250 millis")'), "the PR test's clock advance");
  block = block.replace('TestClock.adjust("250 millis")', `TestClock.adjust("${advance}")`);
}
const a1 = "  const loaderCalls = yield* Ref.make(0);\n";
must(src.includes(a1), "loaderCalls anchor");
src = src.replace(a1, a1 +
  "  const snapshotLoads = yield* Queue.unbounded<void>();\n" +
  "  const httpSnapshot = yield* Ref.make<ThreadSnapshotLoadResult>(\n" +
  '    options?.httpSnapshot ?? { _tag: "unavailable" },\n' +
  "  );\n");
const loaderRe = /  const snapshotLoader = ThreadSnapshotLoader\.ThreadSnapshotLoader\.of\(\{\n[\s\S]*?\n  \}\);\n/;
must(loaderRe.test(src), "snapshotLoader anchor");
src = src.replace(loaderRe,
  "  const snapshotLoader = ThreadSnapshotLoader.ThreadSnapshotLoader.of({\n" +
  "    load: (_prepared, threadId) =>\n" +
  "      Ref.update(loaderCalls, (count) => count + 1).pipe(\n" +
  "        Effect.andThen(Queue.offer(snapshotLoads, undefined)),\n" +
  "        Effect.andThen(\n" +
  "          threadId === THREAD_ID\n" +
  "            ? Ref.get(httpSnapshot)\n" +
  '            : Effect.succeed({ _tag: "unavailable" } satisfies ThreadSnapshotLoadResult),\n' +
  "        ),\n" +
  "      ),\n" +
  "  });\n");
const a3 = "    loaderCalls,\n    lastSubscribeAfterSequence,\n";
must(src.includes(a3), "harness return anchor");
src = src.replace(a3, "    loaderCalls,\n    snapshotLoads,\n    httpSnapshot,\n    lastSubscribeAfterSequence,\n");
const a4 = '  it.effect("does not recreate a deleted cache from a queued save or finalizer"';
must(src.includes(a4), "insertion anchor");
src = src.replace(a4, block + a4);
writeFileSync(target, src);
EOF

# run_at <commit> <log> [clock advance]: overlay the PR test on <commit> and run it.
run_at() {
  git checkout -q -f --detach "$1"
  node "$WORK/overlay.mjs" "$TEST" "$WORK/pr-test.ts" "${3:-}"
  vp test run --reporter=verbose "$TEST" -t "$PATTERN" > "$2" 2>&1 || true
  grep -E "^ +(✓|×) |Tests +[0-9]" "$2" | sed -E 's/^ +//; s/\|@t3tools\/client-runtime\| src\/state\/threads-sync.test.ts > EnvironmentThreads > //' || true
  git checkout -q -f -- .
}
same='✓ .*before it existed \(same session\)'
replaced='✓ .*before it existed \(replaced session\)'
retained='✓ .*retains a deletion instead of restoring the old disk snapshot'

echo "-- #25919 ($SUPER), PR test verbatim"
run_at "$SUPER" "$WORK/super-verbatim.log"
if grep -qE "$same" "$WORK/super-verbatim.log"; then
  pass "verbatim: a thread whose first snapshot 404s stays synchronizing, then goes live and subscribes after sequence 11"
else
  fail "verbatim same-session case does not pass on #25919"
fi
if grep -qE "$replaced" "$WORK/super-verbatim.log"; then
  echo "NOTE  verbatim replaced-session case also passes"
else
  echo "NOTE  verbatim replaced-session case needs more than the PR's 250 ms advance on #25919: its backoff keeps"
  echo "      counting across sessions, so the miss on the new session waits 500 ms (the PR restarts at 250 ms)"
fi

echo "-- #25919 ($SUPER), PR test with a 500 ms clock advance (its second retry delay)"
run_at "$SUPER" "$WORK/super.log" "500 millis"
if grep -qE "$same" "$WORK/super.log" && grep -qE "$replaced" "$WORK/super.log" \
  && grep -qE "$retained" "$WORK/super.log" && grep -qE "Tests +3 passed" "$WORK/super.log"; then
  pass "with a 500 ms advance both PR cases (same and replaced session) recover on #25919, and a delete event still stays deleted"
else
  fail "the PR's cases do not all pass on #25919"
fi

echo "-- parent of #25919 ($PARENT), same test with a 60 s advance (past any retry)"
run_at "$PARENT" "$WORK/parent.log" "60 seconds"
if grep -qE "Tests +2 failed \| 1 passed" "$WORK/parent.log" && grep -qE "$retained" "$WORK/parent.log" \
  && [ "$(grep -c 'Test timed out' "$WORK/parent.log")" -ge 2 ]; then
  pass "on the parent both PR cases time out: a 404 miss parked the thread for good (the bug)"
else
  fail "the PR's cases did not fail on the parent of #25919 as expected"
fi

if [ "$ok" = 1 ]; then
  echo "VERDICT: CLOSE (already-fixed by #25919 / $SUPER)"
  PROOF_DONE=1; exit 0
fi
echo "VERDICT: proof failed; keep the PR open"
exit 1
