#!/usr/bin/env bash
set -euo pipefail

echo "==================== Multilarm Service Installer ===================="

# ------------------------------------------------------------
# Require root / sudo
# ------------------------------------------------------------

if [[ $EUID -ne 0 ]]; then
    echo "Error: This script must be run with sudo."
    echo "Usage: sudo bash multilarmservice.sh"
    exit 1
fi

# ------------------------------------------------------------
# Determine REAL user (safe even if run with sudo)
# ------------------------------------------------------------

if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then
    REAL_USER="$SUDO_USER"
else
    REAL_USER="$(whoami)"
fi

USER_HOME=$(eval echo "~$REAL_USER")
USER_UID=$(id -u "$REAL_USER")
XDG_RUNTIME_DIR="/run/user/$USER_UID"

echo "Target user: $REAL_USER"
echo "Home directory: $USER_HOME"
echo "XDG_RUNTIME_DIR: $XDG_RUNTIME_DIR"

# ------------------------------------------------------------
# Verify Multilarm binary exists
# ------------------------------------------------------------

if [[ ! -f "$USER_HOME/Multilarm" ]]; then
    echo "Error: Multilarm binary not found at $USER_HOME/Multilarm"
    echo "Please run the install script first: sudo bash multilarminstall.sh"
    exit 1
fi

# ------------------------------------------------------------
# Enable bluetooth service if present (non-blocking)
# ------------------------------------------------------------

systemctl enable bluetooth >/dev/null 2>&1 || true

# ------------------------------------------------------------
# Enable systemd-timesyncd for clock synchronisation
# ------------------------------------------------------------

echo "Ensuring time synchronisation service is enabled..."
systemctl enable systemd-timesyncd >/dev/null 2>&1 || true
systemctl start systemd-timesyncd >/dev/null 2>&1 || true

# ------------------------------------------------------------
# Create audio-wait helper script
# ------------------------------------------------------------

WAIT_SCRIPT="$USER_HOME/.multilarm-wait-audio.sh"

tee "$WAIT_SCRIPT" > /dev/null <<'EOL'
#!/usr/bin/env bash

echo "Waiting for audio system..."

# Detect an output device through whichever stack is present. On Pi OS Desktop
# / PipeWire-pulse, pactl talks to the running server; on Pi OS Lite there is no
# PulseAudio server, so we fall back to ALSA (aplay -l lists a card once its
# driver is up). Either signal is enough to proceed. A single 30s loop replaces
# the previous two back-to-back 30s loops so a headless ALSA-only box that has
# no pactl no longer stalls for a full minute before continuing.
audio_ready() {
    if command -v pactl >/dev/null 2>&1 && pactl info >/dev/null 2>&1; then
        # A PulseAudio / PipeWire server is up — require at least one sink.
        pactl list short sinks 2>/dev/null | grep -q .
        return
    fi
    if command -v aplay >/dev/null 2>&1; then
        # No Pulse server — accept any ALSA playback card.
        aplay -l 2>/dev/null | grep -q '^card '
        return
    fi
    return 1
}

for i in {1..30}; do
    if audio_ready; then
        echo "Audio output device detected."
        exit 0
    fi
    echo "  No audio output yet, retrying ($i/30)..."
    sleep 1
done

echo "Warning: No audio output detected after waiting - continuing anyway."
exit 0
EOL

chmod +x "$WAIT_SCRIPT"
chown "$REAL_USER:$REAL_USER" "$WAIT_SCRIPT"

# ------------------------------------------------------------
# Create clock-wait helper script
# ------------------------------------------------------------

CLOCK_WAIT_SCRIPT="$USER_HOME/.multilarm-wait-clock.sh"

tee "$CLOCK_WAIT_SCRIPT" > /dev/null <<'EOL'
#!/usr/bin/env bash

echo "Waiting for clock synchronisation..."

for i in {1..60}; do
    # Check if timedatectl reports the clock as synchronised
    if timedatectl show --property=NTPSynchronized --value 2>/dev/null | grep -qi "yes"; then
        echo "Clock is synchronised."
        exit 0
    fi

    # Fallback: check timedatectl status output for older systemd versions
    if timedatectl status 2>/dev/null | grep -qi "synchronized: yes"; then
        echo "Clock is synchronised."
        exit 0
    fi

    echo "  Clock not synchronised yet, retrying ($i/60)..."
    sleep 2
done

echo "Warning: Clock not synchronised after 2 minutes - continuing anyway."
exit 0
EOL

chmod +x "$CLOCK_WAIT_SCRIPT"
chown "$REAL_USER:$REAL_USER" "$CLOCK_WAIT_SCRIPT"

# ------------------------------------------------------------
# Create systemd USER service
# ------------------------------------------------------------

SERVICE_DIR="$USER_HOME/.config/systemd/user"
SERVICE_FILE="$SERVICE_DIR/multilarm.service"

sudo -u "$REAL_USER" mkdir -p "$SERVICE_DIR"

tee "$SERVICE_FILE" > /dev/null <<EOL
[Unit]
Description=Multilarm
After=default.target sound.target time-sync.target
Wants=time-sync.target

[Service]
Type=simple
Environment=DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
Environment=LD_LIBRARY_PATH=/usr/local/lib
ExecStartPre=$CLOCK_WAIT_SCRIPT
ExecStartPre=$WAIT_SCRIPT
ExecStart=$USER_HOME/Multilarm
Restart=always
RestartSec=5
WorkingDirectory=$USER_HOME

[Install]
WantedBy=default.target
EOL

chown "$REAL_USER:$REAL_USER" "$SERVICE_FILE"

# ------------------------------------------------------------
# Enable lingering (start at boot without login)
# ------------------------------------------------------------

loginctl enable-linger "$REAL_USER"

# ------------------------------------------------------------
# Reload + enable service as user
# ------------------------------------------------------------

echo "Reloading user daemon and enabling Multilarm..."

sudo -u "$REAL_USER" env XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
    systemctl --user daemon-reload

sudo -u "$REAL_USER" env XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
    systemctl --user enable multilarm.service

sudo -u "$REAL_USER" env XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
    systemctl --user restart multilarm.service

# ------------------------------------------------------------
# CPU governor: pin to "performance" on Pi-class ARM
# ------------------------------------------------------------
#
# Kokoro TTS synth on the ondemand governor (Pi default) stalls at the
# bottom frequency band for the first ~200 ms of every inference call
# before ramping up, which doubles first-audio latency. "performance"
# locks all cores at max clock so synth runs at steady-state speed from
# the first cycle. Active cooling (heatsink + fan) is strongly
# recommended — without it the SoC will thermally throttle below
# ondemand's typical sustained clock and you'll net out worse.
#
# Skipped on non-ARM hosts (x86 dev machines): writing "performance"
# there is harmless but pointless because Multilarm isn't shipped for
# x86 Linux as the primary target.

ARCH=$(uname -m)
if [[ "$ARCH" == "aarch64" || "$ARCH" == "armv7l" || "$ARCH" == "armv6l" ]]; then
    echo ""
    echo "--- Installing CPU governor service (performance) ---"

    GOV_SERVICE="/etc/systemd/system/multilarm-cpu-governor.service"

    tee "$GOV_SERVICE" > /dev/null <<'EOL'
[Unit]
Description=Multilarm: pin CPU governor to performance for Kokoro TTS
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=multi-user.target

[Service]
Type=oneshot
RemainAfterExit=yes
# Iterate every CPU's scaling_governor sysfs node. The "|| true" tail
# keeps the unit green on cores whose driver doesn't expose a
# user-writable governor (rare on Pi but possible behind cpufreq drivers
# that don't enumerate the sysfs hook).
ExecStart=/bin/sh -c 'for g in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo performance > "$g" 2>/dev/null || true; done'

[Install]
WantedBy=multi-user.target
EOL

    systemctl daemon-reload
    systemctl enable multilarm-cpu-governor.service >/dev/null 2>&1 || true
    systemctl start  multilarm-cpu-governor.service >/dev/null 2>&1 || true

    # Verify — read back one core's governor as a sanity check.
    CURRENT_GOV=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null || echo "unknown")
    echo "CPU0 governor now: $CURRENT_GOV"
    if [[ "$CURRENT_GOV" != "performance" ]]; then
        echo "Warning: governor did not switch to performance. Check"
        echo "  'systemctl status multilarm-cpu-governor.service' and the"
        echo "  Linux distro's cpufreq driver support."
    fi

    # ------------------------------------------------------------
    # Sudoers drop-in — lets the running Multilarm process toggle the
    # governor unit at start / stop. Multilarm's CpuGovernor module tries
    # `sudo -n /bin/systemctl start|stop multilarm-cpu-governor.service`
    # as one of its fallback rungs. Without this drop-in that rung fails
    # silently (the boot-time unit still pins the governor, but the
    # process can't restore "ondemand" on shutdown).
    #
    # Scoped narrowly:
    #   - Only the systemctl binary, only this one unit name, only
    #     start / stop verbs.
    #   - NOPASSWD because the running service is non-interactive.
    #   - File mode 0440 (sudo refuses to read anything else).
    #   - `visudo -cf` syntax-checks before install — a bad sudoers file
    #     can lock the host out of sudo entirely.
    # ------------------------------------------------------------

    SUDOERS_FILE="/etc/sudoers.d/multilarm-governor"
    SUDOERS_TMP="$(mktemp)"

    cat > "$SUDOERS_TMP" <<EOL
# Installed by Multilarm's multilarmservice.sh. Lets the Multilarm
# process toggle its CPU governor unit without a password. Scope is
# limited to start/stop of one specific unit; remove this file (or
# run multilarmuninstall.sh) to revoke.
$REAL_USER ALL=(root) NOPASSWD: /bin/systemctl start multilarm-cpu-governor.service, /bin/systemctl stop multilarm-cpu-governor.service
EOL

    if visudo -cf "$SUDOERS_TMP" >/dev/null 2>&1; then
        install -m 0440 -o root -g root "$SUDOERS_TMP" "$SUDOERS_FILE"
        echo "Installed sudoers drop-in: $SUDOERS_FILE"
    else
        echo "Warning: sudoers drop-in failed visudo syntax check — not installed."
        echo "         Multilarm will still get the boost from the boot-time unit;"
        echo "         only the in-process restore-on-shutdown path is affected."
    fi
    rm -f "$SUDOERS_TMP"
else
    echo ""
    echo "Skipping CPU governor service (host arch=$ARCH is not Pi-class ARM)."
fi

echo ""
echo "==================== Multilarm Service Installed ===================="
echo ""
echo "Multilarm installed successfully for user: $REAL_USER"
echo "Reboot your Raspberry Pi to test automatic startup."
echo ""
echo "Check status with:"
echo "  systemctl --user status multilarm.service"
echo ""
echo "View logs with:"
echo "  journalctl --user -u multilarm.service -f"
