#!/bin/sh
# Touch gesture daemon for the socktop display. Pass -v to log each detection.
#
# Single source of truth for the lisgd arguments -- referenced by the i3 autostart,
# the systemd unit and tools/test-foreground.sh, so they cannot drift apart.
#
# IMPORTANT: run exactly ONE instance. lisgd does not grab the input device
# exclusively, so two running copies make every swipe fire twice.
set -eu

for c in /usr/local/etc/socktop-swipe.env "$(dirname "$0")/config.env"; do
	[ -r "$c" ] && . "$c" && break
done

: "${TOUCH_DEV:?no TOUCH_DEV -- is the config installed?}"
: "${SCREEN_W:=1024}"
: "${SCREEN_H:=600}"
: "${SWIPE_THRESHOLD:=80}"
: "${SWIPE_LENIENCY:=30}"
: "${FINGER_COUNTS:=1 2 3}"
: "${GESTURE_IN:=RL}"
: "${GESTURE_OUT:=LR}"

SWIPE_CMD=${SWIPE_CMD:-$(dirname "$0")/socktop-swipe}
[ -x /usr/local/bin/socktop-swipe ] && SWIPE_CMD=/usr/local/bin/socktop-swipe

verbose=
replace=no
for a in "$@"; do
	case "$a" in
	-v) verbose=-v ;;
	--replace) replace=yes ;;
	-h | --help)
		echo "usage: socktop-gestures [-v] [--replace]"
		echo "  -v         log each detected gesture"
		echo "  --replace  stop an already-running daemon first"
		exit 0
		;;
	*)
		echo "socktop-gestures: unknown option '$a'" >&2
		exit 2
		;;
	esac
done

# Single-instance guard. lisgd does not grab the input device exclusively, so a
# second copy makes every swipe fire twice -- the carousel appears to skip panes.
# Enforced here rather than left to the caller: the obvious restart one-liner
# `pkill -x lisgd && socktop-gestures` silently starts NOTHING when no daemon was
# running, because pkill exits non-zero when it matches nothing.
running=$(pgrep -x -u "$(id -u)" lisgd 2>/dev/null || true)
if [ -n "$running" ]; then
	if [ "$replace" = yes ]; then
		pkill -x -u "$(id -u)" lisgd || true
		n=0
		while pgrep -x -u "$(id -u)" lisgd >/dev/null 2>&1 && [ "$n" -lt 30 ]; do
			n=$((n + 1))
			sleep 0.1
		done
		if pgrep -x -u "$(id -u)" lisgd >/dev/null 2>&1; then
			echo "socktop-gestures: existing lisgd would not exit" >&2
			exit 1
		fi
	else
		echo "socktop-gestures: lisgd is already running (pid: $(echo "$running" | tr '\n' ' '))" >&2
		echo "  Two instances make every swipe fire twice. Use --replace to restart it." >&2
		exit 1
	fi
fi

if [ ! -e "$TOUCH_DEV" ]; then
	echo "socktop-gestures: $TOUCH_DEV not present" >&2
	exit 1
fi
if [ ! -r "$TOUCH_DEV" ]; then
	echo "socktop-gestures: cannot read $TOUCH_DEV -- are you in the 'input' group?" >&2
	echo "  sudo usermod -aG input $(id -un)   then log out and back in" >&2
	exit 1
fi

# Bind every configured contact count to the same action; see config.env for why.
set --
for f in $FINGER_COUNTS; do
	set -- "$@" -g "$f,$GESTURE_IN,*,*,R,$SWIPE_CMD next"
	set -- "$@" -g "$f,$GESTURE_OUT,*,*,R,$SWIPE_CMD prev"
done

exec lisgd $verbose \
	-d "$TOUCH_DEV" \
	-w "$SCREEN_W" -h "$SCREEN_H" \
	-t "$SWIPE_THRESHOLD" -r "$SWIPE_LENIENCY" \
	"$@"
