#!/usr/bin/env bash
# Togen signage kiosk agent installer (DVI-1201 / DVI-1191 P4b).
#
# Registers this device against a Togen instance (exchanging a one-time
# enrollment token for a permanent agent_token) and installs the systemd
# units that keep the heartbeat and Chromium kiosk running.
#
# Usage:
#   sudo ./install.sh --host https://togen.icastinc.com --token <enrollment_token>
set -euo pipefail

INSTALL_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
STATE_DIR=/etc/togen-signage
CONF_FILE="$STATE_DIR/agent.conf"
TOKEN_FILE="$STATE_DIR/agent.token"

HOST=""
ENROLL_TOKEN=""
HOSTNAME_OVERRIDE=""
KIOSK_USER_OVERRIDE=""
FORCE=0
SKIP_PACKAGES=0

usage() {
  cat <<USAGE
Usage: sudo $0 --host <togen base url> --token <enrollment token> [options]

Required:
  --host, -H <url>       Togen base URL, e.g. https://togen.icastinc.com
                          (the register_url/checkin_url/display_url returned
                          by Admin -> Agents -> Display -> Generate enrollment
                          token all share this host -- use that same host here)
  --token, -t <token>    One-time enrollment token from the same admin action
                          (expires in 1h, single use)

Options:
  --hostname, -n <name>  Override the reported device hostname (default: \$(hostname))
  --kiosk-user <name>    Desktop autologin user to run the kiosk as, on a
                          Wayland-desktop box (Raspberry Pi OS etc.). Default:
                          lightdm autologin-user, else the sudo caller. Ignored
                          on headless boxes (no display manager).
  --force                Re-register even if this device already has an agent token
                          (use after revoking the old agent in Admin -> Agents -> Display)
  --skip-packages        Skip apt-get install of Xorg/Chromium/etc (already provisioned)
  -h, --help             Show this help
USAGE
}

while [ $# -gt 0 ]; do
  case "$1" in
    --host|-H) HOST="$2"; shift 2 ;;
    --token|-t) ENROLL_TOKEN="$2"; shift 2 ;;
    --hostname|-n) HOSTNAME_OVERRIDE="$2"; shift 2 ;;
    --kiosk-user) KIOSK_USER_OVERRIDE="$2"; shift 2 ;;
    --force) FORCE=1; shift ;;
    --skip-packages) SKIP_PACKAGES=1; shift ;;
    -h|--help) usage; exit 0 ;;
    *) echo "Unknown argument: $1" >&2; usage; exit 1 ;;
  esac
done

if [ "$(id -u)" -ne 0 ]; then
  echo "This installer must be run as root (sudo)." >&2
  exit 1
fi

if [ -z "$HOST" ] || [ -z "$ENROLL_TOKEN" ]; then
  usage
  exit 1
fi

HOST="${HOST%/}"

if [ -f "$TOKEN_FILE" ] && [ "$FORCE" -ne 1 ]; then
  echo "$TOKEN_FILE already exists -- this device looks already enrolled." >&2
  echo "Revoke the existing agent in Togen Admin -> Agents -> Display first," >&2
  echo "then re-run with --force to overwrite it." >&2
  exit 1
fi

if [ "$SKIP_PACKAGES" -ne 1 ]; then
  echo "Installing packages (Xorg, Chromium, curl, unclutter)..."
  export DEBIAN_FRONTEND=noninteractive
  apt-get update -y
  apt-get install -y --no-install-recommends \
    xserver-xorg xinit x11-xserver-utils curl ca-certificates unclutter chromium \
    || apt-get install -y --no-install-recommends \
    xserver-xorg xinit x11-xserver-utils curl ca-certificates unclutter chromium-browser
fi

command -v curl >/dev/null 2>&1 || { echo "curl is required (rerun without --skip-packages)" >&2; exit 1; }

DEVICE_HOSTNAME="${HOSTNAME_OVERRIDE:-$(hostname)}"

echo "Registering device '$DEVICE_HOSTNAME' against $HOST ..."
resp=$(curl -sS -w '\n%{http_code}' -X POST "$HOST/signage/agents/register" \
  -H 'Content-Type: application/json' \
  -d "{\"enrollment_token\":\"$ENROLL_TOKEN\",\"hostname\":\"$DEVICE_HOSTNAME\"}")
code=$(printf '%s\n' "$resp" | tail -n1)
body=$(printf '%s\n' "$resp" | sed '$d')

if [ "$code" != "200" ]; then
  echo "Registration failed (HTTP $code): $body" >&2
  echo "Enrollment tokens are single-use and expire after 1h -- mint a fresh" >&2
  echo "one in Admin -> Agents -> Display if this one was already used/expired." >&2
  exit 1
fi

json_field() {
  printf '%s' "$body" | grep -oP "\"$1\"\s*:\s*\"[^\"]*\"" | head -n1 | sed -E "s/.*:\s*\"([^\"]*)\"/\1/"
}

AGENT_TOKEN=$(json_field agent_token)
AGENT_ID=$(json_field agent_id)

if [ -z "$AGENT_TOKEN" ]; then
  echo "Registration response did not include an agent_token: $body" >&2
  exit 1
fi

echo "Registered as agent $AGENT_ID"

mkdir -p "$STATE_DIR"
chmod 700 "$STATE_DIR"

umask 077
printf '%s' "$AGENT_TOKEN" > "$TOKEN_FILE"
chmod 600 "$TOKEN_FILE"
chown root:root "$TOKEN_FILE"

cat > "$CONF_FILE" <<CONF
TOGEN_HOST=$HOST
TOGEN_AGENT_ID=$AGENT_ID
CONF
chmod 644 "$CONF_FILE"

# Heartbeat is identical in both kiosk modes.
install -m 755 "$INSTALL_DIR/checkin.sh" /usr/local/bin/togen-signage-checkin
install -m 644 "$INSTALL_DIR/togen-signage-checkin.service" /etc/systemd/system/togen-signage-checkin.service
install -m 644 "$INSTALL_DIR/togen-signage-checkin.timer" /etc/systemd/system/togen-signage-checkin.timer
systemctl daemon-reload
systemctl enable --now togen-signage-checkin.timer

# --- Kiosk session -----------------------------------------------------------
# Two supported models:
#   Wayland desktop (a display manager is present -- e.g. Raspberry Pi OS with
#     lightdm + labwc autologin): launch Chromium kiosk INSIDE the existing
#     autologin session via a labwc autostart. Starting our own Xorg would fail
#     ("X server already running") because the compositor already owns the
#     display -- this is the DVI-1210 fix for real Pi hardware.
#   Headless (no display manager): the original path -- our own Xorg on tty1 via
#     togen-signage-kiosk.service + xsession, running as root.
if [ -e /etc/systemd/system/display-manager.service ] \
   || systemctl is-active --quiet display-manager 2>/dev/null; then
  echo "Display manager detected -> installing Wayland desktop kiosk (labwc autostart)."

  KIOSK_USER="$KIOSK_USER_OVERRIDE"
  if [ -z "$KIOSK_USER" ] && [ -r /etc/lightdm/lightdm.conf ]; then
    KIOSK_USER=$(sed -n 's/^[[:space:]]*autologin-user[[:space:]]*=[[:space:]]*//p' \
                 /etc/lightdm/lightdm.conf | head -n1)
  fi
  [ -z "$KIOSK_USER" ] && KIOSK_USER="${SUDO_USER:-}"
  if [ -z "$KIOSK_USER" ] || ! id "$KIOSK_USER" >/dev/null 2>&1; then
    echo "Could not determine the desktop autologin user." >&2
    echo "Re-run with --kiosk-user <name> (the user the display auto-logs in as)." >&2
    exit 1
  fi
  KIOSK_HOME=$(getent passwd "$KIOSK_USER" | cut -d: -f6)
  KIOSK_GROUP=$(id -gn "$KIOSK_USER")
  if [ -z "$KIOSK_HOME" ] || [ ! -d "$KIOSK_HOME" ]; then
    echo "Home directory for '$KIOSK_USER' not found." >&2
    exit 1
  fi

  install -m 755 "$INSTALL_DIR/kiosk-launch.sh" /usr/local/bin/togen-signage-kiosk-launch

  # The kiosk runs as the desktop user, so it must be able to read the token.
  # The token is passed in the /display URL anyway, so group-readable is no
  # weaker than the running kiosk itself; keep it off world-readable. Also open
  # the state dir for group traversal (it was created 700 root:root) so the
  # kiosk user can actually reach the group-readable token file.
  chgrp "$KIOSK_GROUP" "$STATE_DIR"
  chmod 750 "$STATE_DIR"
  chown root:"$KIOSK_GROUP" "$TOKEN_FILE"
  chmod 640 "$TOKEN_FILE"

  # Kiosk-only labwc autostart (backs up any existing one once). Overriding the
  # system autostart gives a clean signage screen -- no desktop panel behind it.
  AUTOSTART_DIR="$KIOSK_HOME/.config/labwc"
  mkdir -p "$AUTOSTART_DIR"
  if [ -f "$AUTOSTART_DIR/autostart" ] && [ ! -f "$AUTOSTART_DIR/autostart.togen-bak" ]; then
    cp "$AUTOSTART_DIR/autostart" "$AUTOSTART_DIR/autostart.togen-bak"
  fi
  cat > "$AUTOSTART_DIR/autostart" <<'AUTOSTART'
# Togen signage kiosk (installed by togen-signage install.sh; any previous
# autostart was saved as autostart.togen-bak). Launches Chromium kiosk in this
# Wayland session.
/usr/local/bin/togen-signage-kiosk-launch &
AUTOSTART
  chown -R "$KIOSK_USER":"$KIOSK_GROUP" "$KIOSK_HOME/.config"

  # Best-effort: turn off Pi OS screen blanking so the wall never sleeps.
  if command -v raspi-config >/dev/null 2>&1; then
    raspi-config nonint do_blanking 1 >/dev/null 2>&1 || true
  fi

  # Make sure the headless Xorg service (if a previous install enabled it) is
  # not fighting the compositor for the display.
  systemctl disable --now togen-signage-kiosk.service >/dev/null 2>&1 || true

  echo
  echo "Done."
  echo "Kiosk autostart installed for user '$KIOSK_USER'."
  echo "Apply it now (restarts the desktop session):"
  echo "  sudo systemctl restart display-manager"
  echo "Display URL: $HOST/display?token=<redacted, see $TOKEN_FILE>"
  echo "Check status with:"
  echo "  systemctl status togen-signage-checkin.timer"
  echo "  pgrep -af togen-signage-kiosk-launch"
else
  echo "No display manager -> installing headless Xorg kiosk service."
  install -m 755 "$INSTALL_DIR/xsession" "$STATE_DIR/xsession"
  install -m 644 "$INSTALL_DIR/togen-signage-kiosk.service" /etc/systemd/system/togen-signage-kiosk.service
  systemctl daemon-reload
  systemctl disable --now getty@tty1.service >/dev/null 2>&1 || true
  systemctl enable --now togen-signage-kiosk.service

  echo
  echo "Done."
  echo "Display URL: $HOST/display?token=<redacted, see $TOKEN_FILE>"
  echo "Check status with:"
  echo "  systemctl status togen-signage-kiosk.service"
  echo "  systemctl status togen-signage-checkin.timer"
  echo "  journalctl -u togen-signage-kiosk -f"
fi
