#!/bin/sh
# socktop-swipe next|prev
#
# Walks a linear "zoom carousel" over the socktop session. Each tmux window is
# one group of hosts; within a group the line is the tiled overview, then each
# pane zoomed full-screen in index order; then the next window's overview:
#
#   overview(g0) <-> g0.0 <-> ... <-> g0.N <-> overview(g1) <-> g1.0 <-> ...
#
# "next" moves right and stops at the last pane of the last window. "prev"
# moves back and stops at the first overview. Deliberately no wrap-around: on
# a wall display, wrapping makes it impossible to tell where you are.
#
# This is tmux pane zoom, NOT extra socktop instances. All panes keep running
# and stay connected while hidden, so swiping back shows current data with no
# reconnect, and the polling load on the monitored hosts is constant.
set -eu

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

dir=${1:?usage: socktop-swipe next|prev}

# Ordered window ids (@N) of the session, and the currently active one.
wins=$(tmux list-windows -t "$SOCKTOP_SESSION" -F '#{window_id}' 2>/dev/null) || exit 0
[ -n "$wins" ] || exit 0
WIN=$(tmux display-message -t "$SOCKTOP_SESSION" -p '#{window_id}') || exit 0

prev_win= next_win= seen=no
for w in $wins; do
	if [ "$seen" = yes ]; then next_win=$w; break; fi
	if [ "$w" = "$WIN" ]; then seen=yes; else prev_win=$w; fi
done

state=$(tmux display-message -t "$WIN" -p '#{window_zoomed_flag} #{pane_index} #{window_panes}') || exit 0
zoomed=${state%% *}
rest=${state#* }
idx=${rest%% *}
count=${rest##* }
last=$((count - 1))

zoom_to() {
	# $1 = window id, $2 = pane index.
	# Selecting a different pane auto-unzooms, so zoom explicitly afterwards.
	tmux select-window -t "$1"
	tmux select-pane -t "$1.$2"
	tmux resize-pane -Z -t "$1.$2"
}

overview() {
	# Show window $1 unzoomed.
	tmux select-window -t "$1"
	if [ "$(tmux display-message -t "$1" -p '#{window_zoomed_flag}')" = 1 ]; then
		tmux resize-pane -Z -t "$1"
	fi
}

if [ "$zoomed" = 0 ]; then
	case "$dir" in
	next) zoom_to "$WIN" 0 ;;
	prev)
		# Back out of this group's overview onto the previous group's last pane.
		if [ -n "$prev_win" ]; then
			pl=$(tmux display-message -t "$prev_win" -p '#{window_panes}')
			zoom_to "$prev_win" $((pl - 1))
		fi
		;;
	esac
else
	case "$dir" in
	next)
		if [ "$idx" -lt "$last" ]; then
			zoom_to "$WIN" $((idx + 1))
		elif [ -n "$next_win" ]; then
			tmux resize-pane -Z -t "$WIN.$idx" # unzoom before leaving
			overview "$next_win"
		fi
		;;
	prev)
		if [ "$idx" -gt 0 ]; then
			zoom_to "$WIN" $((idx - 1))
		else
			tmux resize-pane -Z -t "$WIN.$idx" # unzoom -> this group's overview
		fi
		;;
	esac
fi
