#!/bin/sh
# Boot to the Today screen, tap the PROGRAMS tab, and see whether gpe-appmgr
# survives it.
#
#   scripts/tapswitch.sh [seconds-before-tap]
#
# guitest.sh only ever proves the PROGRAMS screen DRAWS: it starts gpe-appmgr
# with show-today=0 so PROGRAMS is the first view. That never runs
# refresh_callback() with a live Today screen to tear down, which is exactly
# what tapping the tab does on the device. This starts on Today instead and
# drives a real pointer click at the PROGRAMS tab, then compares the process
# list before and after -- if gpe-appmgr's PID is gone, the tap killed it and
# the bare root window is what is left under the panel.
set -e
W=$(cd "$(dirname "$0")/.." && pwd)
WAIT=${1:-75}
DBG=/opt/homebrew/opt/e2fsprogs/sbin/debugfs

cp "$W/card/rootfs.ext2" "$W/qemu/gui.ext2"

# start on Today, which is what the device does by default
printf 1 > /tmp/show-today-on
$DBG -w -f /dev/stdin "$W/qemu/gui.ext2" >/dev/null 2>&1 <<EOF
rm /home/lx/.gpe/show-today
write /tmp/show-today-on /home/lx/.gpe/show-today
sif /home/lx/.gpe/show-today mode 0100644
sif /home/lx/.gpe/show-today uid 1000
sif /home/lx/.gpe/show-today gid 1000
EOF

cat > /tmp/tapswitch-inner.sh <<'GT'
#!/bin/sh
exec > /diag.log 2>&1
set -x
B=/bin/busybox
$B mount -t proc proc /proc 2>/dev/null
$B mount -t sysfs sysfs /sys 2>/dev/null
for s in /etc/init.d/populate-var.sh /etc/init.d/lxuser.sh; do
  [ -x "$s" ] && $B sh "$s" start
done
$B mkdir -p /var/tmp /var/log /tmp; $B chmod 1777 /tmp /var/tmp
/usr/bin/Xfbdev -screen 800x600x16 -dpi 100 -br -pn -ac :0 2>/dev/null &
$B sleep 8
export DISPLAY=:0
$B sh /etc/X11/Xinit.d/99psion-session &
$B sleep 55
$B ps w > /ps-before.txt 2>&1          # Today is up
$B sleep 45                            # the host clicks PROGRAMS in here
$B ps w > /ps-after.txt 2>&1
$B cp /var/tmp/xsession-errors.lx /psion-xerr.txt 2>/dev/null
$B sync
$B sleep 600
GT
$DBG -w -f /dev/stdin "$W/qemu/gui.ext2" >/dev/null 2>&1 <<EOF
rm /guitest.sh
write /tmp/tapswitch-inner.sh guitest.sh
sif guitest.sh mode 0100755
EOF

rm -f /tmp/qmp.sock "$W/qemu/gui.log"
cd "$W/qemu"
qemu-system-arm -M versatilepb -m 256 \
  -kernel vmlinuz-versatile -initrd initramfs.gz \
  -drive file=gui.ext2,format=raw,if=none,id=hd0 \
  -device lsi53c895a,id=scsi0 -device scsi-hd,drive=hd0,bus=scsi0.0 \
  -append 'console=ttyAMA0 rw' -serial file:gui.log -display none \
  -qmp unix:/tmp/qmp.sock,server,nowait > /dev/null 2>&1 &
QP=$!

python3 - "$WAIT" <<'PY'
import socket, json, sys, time
time.sleep(int(sys.argv[1]))
s = socket.socket(socket.AF_UNIX); s.connect('/tmp/qmp.sock')
f = s.makefile('rw'); f.readline()
def cmd(c, **a):
    f.write(json.dumps({"execute": c, "arguments": a} if a else {"execute": c}) + "\n")
    f.flush(); return f.readline().strip()
cmd("qmp_capabilities")
# the Today screen as it stands
cmd("screendump", filename="/tmp/tap-before.ppm"); time.sleep(2)
# PROGRAMS is the second tab: strip x 774..799, tab 2 spans y 101..202
for c in ('mouse_move 400 300', 'mouse_move 790 150',
          'mouse_button 1', 'mouse_button 0'):
    print(cmd("human-monitor-command", **{"command-line": c}))
    time.sleep(1)
time.sleep(25)
cmd("screendump", filename="/tmp/tap-after.ppm")
s.close()
PY

for p in before after; do
  [ -f /tmp/tap-$p.ppm ] && python3 -c "from PIL import Image; Image.open('/tmp/tap-$p.ppm').convert('RGB').save('$W/qemu/tap-$p.png')"
done
sleep 45
kill $QP 2>/dev/null || true
sleep 2
for f in ps-before.txt ps-after.txt psion-xerr.txt diag.log; do
  rm -f "$W/qemu/$f"
  $DBG -R "dump /$f $W/qemu/$f" gui.ext2 >/dev/null 2>&1
done
echo "== gpe-appmgr BEFORE the tap:"
grep -a 'gpe-appmgr' "$W/qemu/ps-before.txt" 2>/dev/null | sed 's/^/   /' || echo "   (not running)"
echo "== gpe-appmgr AFTER the tap:"
grep -a 'gpe-appmgr' "$W/qemu/ps-after.txt" 2>/dev/null | sed 's/^/   /' || echo "   *** GONE -- the tap killed it ***"
echo "== last X session errors:"
tail -6 "$W/qemu/psion-xerr.txt" 2>/dev/null | sed 's/^/   /'
