#!/bin/sh
# ALARM on Switch - shell init: WiFi + SSH + X desktop on Switch screen
# (systemd requires kernel >=5.10; we run NVIDIA's 4.9 L4T kernel)

LOG=/mnt/boot/alarm-init.log

# Mount boot partition for logging
mkdir -p /mnt/boot 2>/dev/null
mount /dev/mmcblk0p1 /mnt/boot 2>/dev/null || mount /dev/mmcblk1p1 /mnt/boot 2>/dev/null
echo "INIT_DEBUG_RAN $(date)" > "$LOG"

# Essential filesystems
mount -t proc proc /proc 2>/dev/null
mount -t sysfs sysfs /sys 2>/dev/null
mount -t devtmpfs devtmpfs /dev 2>/dev/null
mkdir -p /dev/pts /dev/shm /run /tmp
mount -t devpts devpts /dev/pts 2>/dev/null
mount -t tmpfs tmpfs /run 2>/dev/null
mount -t tmpfs tmpfs /tmp 2>/dev/null

# devtmpfs hides these; without them pacman-key fails (/dev/fd/63 missing)
[ -e /dev/fd ] || ln -s /proc/self/fd /dev/fd
[ -e /dev/stdin ] || ln -s /proc/self/fd/0 /dev/stdin
[ -e /dev/stdout ] || ln -s /proc/self/fd/1 /dev/stdout
[ -e /dev/stderr ] || ln -s /proc/self/fd/2 /dev/stderr
[ -e /dev/core ] || ln -s /proc/kcore /dev/core

# DNS (systemd-resolved symlink is dangling without systemd)
rm -f /etc/resolv.conf
printf 'nameserver 192.168.4.1\nnameserver 1.1.1.1\n' > /etc/resolv.conf

echo "Kernel: $(uname -r)" >> "$LOG"

# --- Kill splash screen ---
killall -9 ply-image 2>/dev/null
killall -9 plymouthd 2>/dev/null
sleep 1
for f in /sys/class/graphics/fb*; do
    [ -d "$f" ] && echo 0 > "$f/blank" 2>/dev/null
done

# --- SSH ---
mkdir -p /run/sshd 2>/dev/null
ssh-keygen -A 2>/dev/null
/usr/sbin/sshd 2>/dev/null
echo "sshd rc=$?" >> "$LOG"

# --- dbus: without it X logs a connection error every 10s and anything
# needing the system bus fails. Kernel 4.9 has no systemd to start it. ---
mkdir -p /run/dbus
dbus-uuidgen --ensure 2>> "$LOG"
setsid dbus-daemon --system --nopidfile >> "$LOG" 2>&1 &
sleep 1
[ -S /run/dbus/system_bus_socket ] && echo "dbus: up" >> "$LOG" || echo "dbus: NO SOCKET" >> "$LOG"

# --- udevd: for input hotplug ---
# (systemd-udevd cannot fully run on 4.9 - statx ENOSYS - but it still
#  creates nodes and lets X see devices; X config is generated explicitly)
/usr/lib/systemd/systemd-udevd --daemon 2>> "$LOG"
echo "udevd rc=$?" >> "$LOG"

# --- WiFi ---
modprobe brcmfmac 2>/dev/null
echo "modprobe rc=$?" >> "$LOG"
sleep 5

if ip link show wlan0 >/dev/null 2>&1; then
    echo "wlan0 found" >> "$LOG"
    ip link set wlan0 up 2>/dev/null
    killall wpa_supplicant 2>/dev/null
    sleep 1
    /usr/sbin/wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf -D nl80211 -B 2>> "$LOG"
    echo "wpa rc=$?" >> "$LOG"
    sleep 8
    dhcpcd wlan0 2>> "$LOG"
    echo "dhcpcd rc=$?" >> "$LOG"
    sleep 8
else
    echo "NO wlan0" >> "$LOG"
fi

# --- Joy-Con rail driver (serdev, both rails) ---
modprobe joycon-serdev 2>> "$LOG"
echo "joycon rc=$?" >> "$LOG"
# wait for both rails to handshake (takes ~1-2s after detect)
i=0
while [ $i -lt 15 ]; do
    grep -q "Left Joy-Con Serial" /proc/bus/input/devices 2>/dev/null && \
    grep -q "Right Joy-Con Serial" /proc/bus/input/devices 2>/dev/null && break
    sleep 1; i=$((i+1))
done
echo "joycon wait ${i}s" >> "$LOG"

# --- Joy-Con -> mouse/keyboard mapper (official Switchroot L4T mapping) ---
# Must run BEFORE gen-xorg-input.sh: that script binds X to the virtual
# devices this creates. Without it X would bind the raw analog sticks, which
# snap the cursor to centre on release.
modprobe uinput 2>> "$LOG"

# --- DRM render nodes (/dev/dri) for Qt/KDE + hardware accel ---
# tegra-udrm needs modeset=1: the module's default is modeset=0, in which
# case its init returns -EINVAL and modprobe reports "Invalid argument".
# nvgpu provides /dev/nvhost-gpu, which tegra-udrm relies on for the GPU.
modprobe nvgpu 2>> "$LOG"
modprobe tegra-udrm modeset=1 2>> "$LOG"
# devtmpfs recreates these root:root 0600 on every boot, and udev rules are
# unreliable on this 4.9 kernel, so set the perms here instead.
if [ -e /dev/dri/card0 ]; then
    chgrp video /dev/dri/card0 2>/dev/null
    chmod 660 /dev/dri/card0 2>/dev/null
fi
if [ -e /dev/dri/renderD128 ]; then
    chgrp render /dev/dri/renderD128 2>/dev/null
    chmod 660 /dev/dri/renderD128 2>/dev/null
fi
echo "dri: $(ls /dev/dri 2>/dev/null | tr "\n" " ")" >> "$LOG"

setsid /usr/local/bin/jcmapper >> /root/jcmapper.log 2>&1 &
i=0
while [ $i -lt 10 ]; do
    grep -q 'Name="ALARM JoyCon Mouse"' /proc/bus/input/devices 2>/dev/null && break
    sleep 1; i=$((i+1))
done
echo "jcmapper wait ${i}s" >> "$LOG"

# --- Generate X input config (eventN changes per boot, udevd is unreliable) ---
/usr/local/bin/gen-xorg-input.sh >> "$LOG" 2>&1

echo "=== STATUS ===" >> "$LOG"
ip addr show >> "$LOG" 2>/dev/null
ip route show >> "$LOG" 2>/dev/null

sync
echo "Starting X desktop" >> "$LOG"

# --- Start X + OpenBox on the Switch display ---
# Started detached so this init can hand off to a shell; X restartable.
export HOME=/root
cd /root
setsid startx /root/.xinitrc -- :0 >> /root/xorg-boot.log 2>&1 &
sleep 1

echo "Handing off to shell (X running in background)" >> "$LOG"
exec /bin/bash --login
