#!/bin/sh
# Не выпускать браузер, пока показывать некуда и нечего.
set -eu

PORT="${SCREEN_PORT:-3000}"
TIMEOUT="${DASHDASH_WAIT_TIMEOUT:-120}"
BOOT_PAGE="${DASHDASH_BOOT_PAGE:-/usr/local/share/dashdash/boot.html}"
BOOT_PID=""

display_connected() {
	for status in /sys/class/drm/card*-*/status; do
		[ -f "$status" ] || continue
		if [ "$(cat "$status" 2>/dev/null)" = "connected" ]; then
			return 0
		fi
	done
	return 1
}

i=0
while [ "$i" -lt "$TIMEOUT" ]; do
	if display_connected; then
		break
	fi
	i=$((i + 1))
	sleep 1
done
if ! display_connected; then
	echo "dashdash: за ${TIMEOUT}с не появилось ни одного подключённого экрана" >&2
	exit 1
fi

# Экран есть, агента ещё нет.
show_boot_screen() {
	[ -f "$BOOT_PAGE" ] || return 0
	command -v cage >/dev/null 2>&1 || return 0
	command -v cog >/dev/null 2>&1 || return 0
	# Тот же фон, что у киоска, и по той же причине.
	bg=""
	if cog --help 2>&1 | grep -q -- "--bg-color"; then
		bg="--bg-color=${KIOSK_BG_COLOR:-#0f1420}"
	fi
	# shellcheck disable=SC2086 # bg — аргумент или пусто
	# Та же переменная, что у киоска.
	WLR_LIBINPUT_NO_DEVICES="${WLR_LIBINPUT_NO_DEVICES:-1}"
	export WLR_LIBINPUT_NO_DEVICES
	setsid cage -- cog --platform=wl $bg "file://${BOOT_PAGE}" >/dev/null 2>&1 &
	BOOT_PID=$!
}

boot_screen_alive() {
	[ -n "$BOOT_PID" ] || return 1
	kill -0 "$BOOT_PID" 2>/dev/null
}

# Никто больше не держит видеокарту?
drm_is_free() {
	for proc in /proc/[0-9]*; do
		if ls -l "$proc/fd" 2>/dev/null | grep -q 'dri/card'; then
			return 1
		fi
	done
	return 0
}

hide_boot_screen() {
	# Номер забираем себе и обнуляем сразу.
	pid="$BOOT_PID"
	BOOT_PID=""
	[ -n "$pid" ] || return 0

	# Минус перед номером — вся группа: оболочка, композитор, браузер.
	kill -TERM "-$pid" 2>/dev/null || true

	# Ждать без срока нельзя.
	waited=0
	while [ "$waited" -lt 5 ]; do
		kill -0 "$pid" 2>/dev/null || break
		waited=$((waited + 1))
		sleep 1
	done
	kill -KILL "-$pid" 2>/dev/null || true

	# И только теперь — пока ядро не отпустит видеокарту.
	waited=0
	while [ "$waited" -lt 10 ]; do
		if drm_is_free; then
			break
		fi
		waited=$((waited + 1))
		sleep 1
	done
	return 0
}

trap hide_boot_screen EXIT INT TERM

show_boot_screen

i=0
while [ "$i" -lt "$TIMEOUT" ]; do
	if curl -fsS -o /dev/null "http://127.0.0.1:${PORT}/health"; then
		hide_boot_screen
		exit 0
	fi

	# При холодном старте заставка часто не переживает первую попытку.
	if ! boot_screen_alive && [ $((i % 5)) -eq 0 ]; then
		BOOT_PID=""
		show_boot_screen
	fi

	i=$((i + 1))
	sleep 1
done

echo "dashdash: агент не ответил на :${PORT} за ${TIMEOUT}с" >&2
exit 1
