#!/bin/sh

# PROVIDE: framework_autorotate
# REQUIRE: LOGIN
# KEYWORD: nojail shutdown
#
# Framework Laptop 12 autorotate (Chrome EC accel + TBMD -> RandR/CTM).
# Safe with XDM greeter.  KDE/GNOME/XFCE typically need no chrome hook;
# optional ~/.framework_autorotate is opt-in (e.g. FVWM taskbar refresh).
#
# Enable in /etc/rc.conf:
#	framework_autorotate_enable="YES"
#
# Mode (always vs tablet-gated):
#	framework_autorotate_mode="always"	# default: rotate whenever accel says
#	framework_autorotate_mode="tablet"	# only while EC TBMD=1; else normal
#
# Optional:
#	framework_autorotate_display=":0"
#	framework_autorotate_hook=".framework_autorotate"	# under $HOME
#	framework_autorotate_flags=""
#	framework_autorotate_xlogin_recenter="/usr/local/libexec/framework_autorotate/xlogin_recenter"
#	framework_autorotate_logfile="/var/log/framework_autorotate.log"	# opt-in; empty = no log
#
# Chrome-hook login is always auto-detected (non-root X client; FvwmMFL
# owner if present).
#
# Per-user chrome hook (~/.framework_autorotate), spirit of .xinitrc:
# if that file exists in the logged-in user's home, it is run after each
# rotate as that user with CHROME_WIDTH / CHROME_HEIGHT /
# FRAMEWORK_AUTOROTATE_ROTATION set.  Absent = no-op (usual for KDE/GNOME/XFCE).
#
# daemon(8) note: -p/-o/-P enable supervision mode.  The pidfile must track
# the *supervisor* (-P), not the child (-p).  With -p, stop waits for the
# child then start races the still-locked supervisor -> "already running"
# and status says not running (child gone, lock remains).
#

. /etc/rc.subr

name="framework_autorotate"
rcvar=framework_autorotate_enable
desc="Framework Laptop 12 display autorotate"

load_rc_config $name

: ${framework_autorotate_enable:=NO}
: ${framework_autorotate_mode:=always}
: ${framework_autorotate_display:=:0}
: ${framework_autorotate_hook:=.framework_autorotate}
: ${framework_autorotate_flags:=}
: ${framework_autorotate_xlogin_recenter:=/usr/local/libexec/framework_autorotate/xlogin_recenter}
: ${framework_autorotate_logfile:=}

pidfile="/var/run/${name}.pid"
# Supervisor is what holds the pidfile lock under daemon(8) -P.
procname="/usr/sbin/daemon"
command="/usr/sbin/daemon"
framework_autorotate_bin="/usr/local/sbin/framework_autorotate"
start_precmd="${name}_prestart"
start_cmd="${name}_start"

framework_autorotate_prestart()
{
	if [ ! -x "$framework_autorotate_bin" ]; then
		err 1 "$framework_autorotate_bin not installed"
	fi
	case "$framework_autorotate_mode" in
	always|tablet) : ok ;;
	*)
		err 1 "framework_autorotate_mode must be always or tablet"
		;;
	esac
	if [ ! -c /dev/io ]; then
		warn "/dev/io missing; autorotate needs io privilege"
	fi
}

framework_autorotate_start()
{
	local auth

	#
	# XDM often starts from ttys after LOGIN.  The daemon itself pauses
	# until DISPLAY is ready; pick the newest :0 cookie if present.
	# Chrome-hook login is resolved per-rotate inside the binary.
	#
	auth=$( ls -t /var/db/xdm/authdir/authfiles/A:0-* 2> /dev/null |
	    head -1 )

	# -P: supervisor PID in pidfile (rc.subr stop/status target).
	# -t: setproctitle for admin visibility.
	# -o: opt-in log capture only when framework_autorotate_logfile is set.
	# -v on the binary likewise only when logging (otherwise discarded).
	if [ -n "$framework_autorotate_logfile" ]; then
		/usr/sbin/daemon -f -P "$pidfile" -t framework_autorotate \
		    -o "$framework_autorotate_logfile" \
		    /usr/bin/env \
		    DISPLAY="$framework_autorotate_display" \
		    ${auth:+XAUTHORITY="$auth"} \
		    FRAMEWORK_AUTOROTATE_HOOK_NAME="$framework_autorotate_hook" \
		    FRAMEWORK_AUTOROTATE_XLOGIN_RECENTER="$framework_autorotate_xlogin_recenter" \
		    PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" \
		    "$framework_autorotate_bin" -i 500 -m "$framework_autorotate_mode" -v \
		    $framework_autorotate_flags
	else
		/usr/sbin/daemon -f -P "$pidfile" -t framework_autorotate \
		    /usr/bin/env \
		    DISPLAY="$framework_autorotate_display" \
		    ${auth:+XAUTHORITY="$auth"} \
		    FRAMEWORK_AUTOROTATE_HOOK_NAME="$framework_autorotate_hook" \
		    FRAMEWORK_AUTOROTATE_XLOGIN_RECENTER="$framework_autorotate_xlogin_recenter" \
		    PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" \
		    "$framework_autorotate_bin" -i 500 -m "$framework_autorotate_mode" \
		    $framework_autorotate_flags
	fi

	#
	# daemon(8) creates pidfile/logfile mode 0600 regardless of umask.
	# World-readable like xdm.pid/sshd.pid so unprivileged
	# `service framework_autorotate status` works (rc.subr check_pidfile
	# does `read < pidfile`; unreadable yields a spurious
	# "eval: cannot open … Permission denied" from /bin/sh — not an eval
	# in this script).
	#
	chmod 644 "$pidfile" 2> /dev/null || true
	if [ -n "$framework_autorotate_logfile" ]; then
		chmod 644 "$framework_autorotate_logfile" 2> /dev/null || true
	fi
}

#
# rc.subr snapshots ${name}_user for su(1) before start_precmd. Chrome-hook
# login is resolved inside the binary — never via this knob — so drop it
# before run_rc_command lest a curious rc.conf entry wrap start/stop in su
# and break stop/restart.
#
if [ "${framework_autorotate_user:-}" ]; then
	warn "ignoring framework_autorotate_user (rc.subr su target;" \
	    "chrome-hook login is auto-detected)"
	unset framework_autorotate_user
fi
run_rc_command "$1"
