#!/usr/bin/env bash
# r4 now-tier acceptance harness. MUST run inside a network namespace: the v1.0.x binaries
# predate the regtest seed-injection fix and would otherwise dial the live DragonX network.
set -u
OLD=/home/dev/dragonx/release/dragonx-1.0.1-linux-amd64
NEW=/home/dev/dragonx-dev/src
ROOT=/tmp/claude-1000/-home-dev/45a644d6-ea0b-4b7c-8ec7-6ccb1a64afa7/scratchpad/r4lab
PASS=0; FAIL=0
ok(){ echo "  PASS  $1"; PASS=$((PASS+1)); }
no(){ echo "  FAIL  $1"; FAIL=$((FAIL+1)); }

# --- hard guardrail: refuse to run unisolated ---
if [ "$(ip route show 2>/dev/null | wc -l)" != "0" ]; then
  echo "REFUSING: not in an isolated netns (routes present). Run under: unshare -rn"; exit 90
fi
ip link set lo up 2>/dev/null
echo "isolation: $(ip route show | wc -l) routes, $(ip -o link | wc -l) interface(s)"

conf(){ printf 'regtest=1\nrpcuser=t\nrpcpassword=t\nlisten=0\ndnsseed=0\n' > "$1/DRAGONX.conf"; }
start(){ # $1=bindir $2=datadir $3=extra
  "$1/dragonxd" -regtest -datadir="$2" -connect=0 -listen=0 -dnsseed=0 $3 -daemon >/dev/null 2>&1
  for i in $(seq 40); do "$1/dragonx-cli" -regtest -datadir="$2" -rpcuser=t -rpcpassword=t getblockcount >/dev/null 2>&1 && return 0; sleep 2; done
  return 1; }
cli(){ "$1/dragonx-cli" -regtest -datadir="$2" -rpcuser=t -rpcpassword=t "${@:3}" 2>&1; }
stopn(){ cli "$1" "$2" stop >/dev/null 2>&1; sleep 6; }

rm -rf "$ROOT"; mkdir -p "$ROOT"

echo; echo "### build victim wallets with the OLD binary (v1.0.1) ###"
mkdir -p "$ROOT/base/regtest"; conf "$ROOT/base/regtest"
start "$OLD" "$ROOT/base/regtest" "" || { echo "old node failed to start"; exit 91; }
[ "$(cli "$OLD" "$ROOT/base/regtest" getconnectioncount)" = "0" ] && ok "victim-maker has 0 peers (isolated)" || no "victim-maker NOT isolated -- ABORT"
cli "$OLD" "$ROOT/base/regtest" getnewaddress   >/dev/null
cli "$OLD" "$ROOT/base/regtest" z_getnewaddress >/dev/null
ZBEFORE=$(cli "$OLD" "$ROOT/base/regtest" z_listaddresses | tr -d ' \n')
stopn "$OLD" "$ROOT/base/regtest"

for v in C A B; do cp -a "$ROOT/base" "$ROOT/$v"; done

# A = salvaged by v1.0.1 (drops hdchain).  B = A then USED on v1.0.1 (persists a bogus chain).
start "$OLD" "$ROOT/A/regtest" "-salvagewallet" && stopn "$OLD" "$ROOT/A/regtest"
start "$OLD" "$ROOT/B/regtest" "-salvagewallet" && stopn "$OLD" "$ROOT/B/regtest"
start "$OLD" "$ROOT/B/regtest" "" && { cli "$OLD" "$ROOT/B/regtest" z_getnewaddress >/dev/null; stopn "$OLD" "$ROOT/B/regtest"; }

echo "  A hdchain records: $(strings "$ROOT/A/regtest/regtest/wallet.dat" | grep -c hdchain)  (expect 0)"
echo "  B hdchain records: $(strings "$ROOT/B/regtest/regtest/wallet.dat" | grep -c hdchain)  (expect >=1)"

echo; echo "### open each on the NEW binary ###"
for v in C A B; do
  D="$ROOT/$v/regtest"; L="$D/regtest/debug.log"
  WDAT="$D/regtest/wallet.dat"
  [ -f "$WDAT" ] || { echo "  FAIL  $v: wallet.dat not found at $WDAT"; exit 92; }
  # NOT a byte-identical check: normal startup (keypool top-up, bestblock) rewrites wallet.dat for
  # ANY wallet, healthy ones included -- verified with a control. The precise claim is that the
  # degraded path never SYNTHESISES an hdchain record, so count that instead.
  HD1=$(strings "$WDAT" | grep -c hdchain)
  : > "$L" 2>/dev/null
  if start "$NEW" "$D" "-exportdir=$D/exp"; then
    STARTED=yes; DEG=$(grep -c "DEGRADED" "$L" 2>/dev/null)
    MISS=$(grep -c "hdchain record is missing" "$L" 2>/dev/null)
    MISM=$(grep -c "does not belong to this wallet" "$L" 2>/dev/null)
    if [ "$v" = "A" ]; then
      mkdir -p "$D/exp"; EXP=$(cli "$NEW" "$D" z_exportwallet r4dump 2>&1 | head -1)
      DUMP=$(find "$D" -name 'r4dump' 2>/dev/null | head -1)
      ZNEW=$(cli "$NEW" "$D" z_getnewaddress); TNEW=$(cli "$NEW" "$D" getnewaddress)
    fi
    stopn "$NEW" "$D"
  else STARTED=no; DEG=0; MISS=0; MISM=0; fi
  HD2=$(strings "$WDAT" | grep -c hdchain)

  case $v in
    C) [ "$STARTED" = yes ] && ok "C healthy wallet opens" || no "C healthy wallet failed to open"
       [ "$DEG" = "0" ] && ok "C no false positive (not flagged degraded)" || no "C FALSE POSITIVE: healthy wallet flagged" ;;
    A) [ "$STARTED" = yes ] && ok "A salvaged wallet opens (was DB_CORRUPT before)" || no "A salvaged wallet still refuses to open"
       [ "$MISS" -ge 1 ] && ok "A flagged: hdchain missing" || no "A not flagged as missing-hdchain"
       [ "$HD1" = "0" ] && [ "$HD2" = "0" ] && ok "A no hdchain synthesised (degraded path persists nothing)" || no "A hdchain record appeared ($HD1 -> $HD2)"
       echo "$ZNEW" | grep -qi 'error' && ok "A z_getnewaddress refused cleanly (derivation gated)" || no "A z_getnewaddress derived anyway: $ZNEW"
       echo "$TNEW" | grep -qiE '^R[a-zA-Z0-9]+$' && ok "A getnewaddress still works (legacy random t-key)" || no "A getnewaddress broke: $TNEW"
       if [ -n "${DUMP:-}" ] && [ -f "$DUMP" ]; then
         grep -qE '^# HDSeed=[0-9a-f]' "$DUMP" && no "E z_exportwallet emitted an HDSeed line on a degraded wallet" || ok "E z_exportwallet emitted no bogus HDSeed line"
       else echo "  SKIP  E (no dump produced: $EXP)"; fi ;;
    B) [ "$STARTED" = yes ] && ok "B poisoned wallet opens" || no "B poisoned wallet failed to open"
       [ "$MISM" -ge 1 ] && ok "B CASE-3 DETECTOR FIRED (seedFp mismatch)" || no "B case-3 detector did NOT fire" ;;
  esac
done
echo; echo "### $PASS passed, $FAIL failed ###"
exit $FAIL
