#!/bin/sh
# Relays a serial console through a cleave clone's unversioned files, so
# someone with only Fossil access can watch and type on a board's console.
#
#   tools/serial-relay.sh REPOSITORY [DEVICE [NAME]]
#
# REPOSITORY  a cleave clone whose remote login has the y capability
# DEVICE      the serial port, /dev/ttyACM0 by default (115200 8N1)
# NAME        files go under serial/NAME/, "beagley-ai" by default
#
# Everything the port sends is appended to serial/NAME/console.log and
# pushed about every PERIOD seconds (default 15). Text put in
# serial/NAME/input after its first line (a sequence tag, so the same text
# can be sent twice) is written to the port once each time it changes, with
# newlines sent as carriage returns. Needs only busybox and fossil.
set -eu

repo=$1
dev=${2:-/dev/ttyACM0}
name=${3:-beagley-ai}
period=${PERIOD:-15}
dir=${RELAY_DIR:-$HOME/serial-relay/$name}
mkdir -p "$dir"
log=$dir/console.log
: >>"$log"

stty -F "$dev" 115200 cs8 -cstopb -parenb raw -echo
cat "$dev" >>"$log" &
reader=$!
trap 'kill $reader 2>/dev/null' EXIT INT TERM

# input already there at startup was meant for an earlier session
sent=none
fossil uv sync -R "$repo" >/dev/null 2>&1 || true
if fossil uv export "serial/$name/input" "$dir/input" -R "$repo" 2>/dev/null; then
	sent=$(sha256sum "$dir/input" | cut -d" " -f1)
fi
last_size=-1
while kill -0 $reader 2>/dev/null; do
	size=$(wc -c <"$log")
	if [ "$size" != "$last_size" ]; then
		fossil uv add "$log" --as "serial/$name/console.log" -R "$repo"
		last_size=$size
	fi
	fossil uv sync -R "$repo" >/dev/null 2>&1 || echo "serial-relay: sync failed" >&2
	if fossil uv export "serial/$name/input" "$dir/input" -R "$repo" 2>/dev/null; then
		sum=$(sha256sum "$dir/input" | cut -d' ' -f1)
		if [ "$sum" != "$sent" ]; then
			sed 1d "$dir/input" | tr '\n' '\r' >"$dev"
			sent=$sum
		fi
	fi
	sleep "$period"
done
