#!/usr/bin/env python3
# Drive the DF guest's serial console over unix socket: log everything,
# and when the DDB "db>" prompt appears, send backtrace commands.
import socket, sys, time, re

SOCK = sys.argv[1] if len(sys.argv) > 1 else "dfbsd-qemu/serial.sock"
OUT = open(sys.argv[2] if len(sys.argv) > 2 else "/tmp/opencode/serial_full.log", "wb")
deadline = time.time() + int(sys.argv[3] if len(sys.argv) > 3 else 420)

s = socket.socket(socket.AF_UNIX)
# wait for socket to appear
while True:
    try:
        s.connect(SOCK); break
    except (FileNotFoundError, ConnectionRefusedError):
        if time.time() > deadline: sys.exit("no serial socket")
        time.sleep(1)

s.setblocking(False)
buf = b""
sent_trace = 0
cmds = [b"trace\n", b"bt\n", b"call dumpsys\n"]
last_data = time.time()

while time.time() < deadline:
    try:
        d = s.recv(65536)
        if d:
            OUT.write(d); OUT.flush()
            buf = (buf + d)[-8000:]
            last_data = time.time()
    except BlockingIOError:
        pass
    # DDB prompt detection: "db> " at the tail
    if re.search(rb"(^|\n)db> ?$", buf) and sent_trace < len(cmds):
        time.sleep(0.5)
        s.sendall(cmds[sent_trace])
        sent_trace += 1
        time.sleep(3)
    # stop when trace printed or guest booted to login
    if b"login:" in buf[-500:] or b"Trace:" in buf and sent_trace >= 3:
        time.sleep(5)
        break
print("done, sent", sent_trace)
