#!/usr/bin/env bash
# Suppress kiosk-breaking desktop dialogs on Raspberry Pi OS (LXDE / labwc).
#
# Blocks:
#   1) NetworkManager WiFi password re-prompt (psk pre-filled) after WLAN drop
#   2) USB / removable-media "Removable medium is inserted" / Open in File Manager
#
# Run as topbox (not root). Uses sudo for system xdg + NetworkManager secrets.
#
#   bash ~/DyzineFrame/harden_pi_desktop.sh
#   (also invoked from install_script.sh)

set -euo pipefail

if [[ "${EUID}" -eq 0 ]]; then
  echo "DO NOT RUN THIS SCRIPT AS ROOT — run as topbox." >&2
  exit 1
fi

HOME_DIR="${HOME}"
AUTOSTART="${HOME_DIR}/.config/autostart"
mkdir -p "${AUTOSTART}"

echo "=== harden_pi_desktop ==="

# ---------------------------------------------------------------------------
# USB / removable media
# Dialog "Removable medium is inserted" comes from libfm + pcmanfm volume mgr.
# User config alone is not enough if a desktop pcmanfm is already running, or if
# /etc/xdg defaults still have autorun=1 — patch both and reload pcmanfm.
# ---------------------------------------------------------------------------
_set_ini_keys() {
  # _set_ini_keys <file> <section> key=val [key=val ...]
  local conf=$1
  local section=$2
  shift 2
  local dir
  dir=$(dirname "${conf}")
  mkdir -p "${dir}"
  if [[ ! -f "${conf}" ]]; then
    printf '[%s]\n' "${section}" >"${conf}"
  fi
  if ! grep -q "^\[${section}\]" "${conf}"; then
    printf '\n[%s]\n' "${section}" >>"${conf}"
  fi
  local kv key val
  for kv in "$@"; do
    key="${kv%%=*}"
    val="${kv#*=}"
    if grep -q "^${key}=" "${conf}"; then
      sed -i "s|^${key}=.*|${key}=${val}|" "${conf}"
    else
      sed -i "/^\[${section}\]/a ${key}=${val}" "${conf}"
    fi
  done
}

_write_pcmanfm_volume() {
  local conf=$1
  _set_ini_keys "${conf}" volume \
    mount_on_startup=0 \
    mount_removable=0 \
    autorun=0
  echo "pcmanfm: ${conf}"
}

# Known profiles + any already present under ~/.config/pcmanfm/
_profiles=(LXDE-pi LXDE default labwc rpd-x rpd-w)
if [[ -d "${HOME_DIR}/.config/pcmanfm" ]]; then
  while IFS= read -r -d '' d; do
    _profiles+=("$(basename "${d}")")
  done < <(find "${HOME_DIR}/.config/pcmanfm" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null)
fi
# unique
mapfile -t _profiles < <(printf '%s\n' "${_profiles[@]}" | awk 'NF && !seen[$0]++')

for profile in "${_profiles[@]}"; do
  _write_pcmanfm_volume "${HOME_DIR}/.config/pcmanfm/${profile}/pcmanfm.conf"
done

# libfm drives the "Removable medium is inserted" chooser (Open in File Manager).
_set_ini_keys "${HOME_DIR}/.config/libfm/libfm.conf" config autorun=0
echo "libfm: ${HOME_DIR}/.config/libfm/libfm.conf (autorun=0)"

# System defaults (survive new profiles / first login).
if [[ -d /etc/xdg/pcmanfm ]]; then
  while IFS= read -r -d '' conf; do
    sudo mkdir -p "$(dirname "${conf}")"
    if [[ ! -f "${conf}" ]]; then
      echo "[volume]" | sudo tee "${conf}" >/dev/null
    fi
    # Ensure [volume] + keys via a small sudo sed/append.
    if ! sudo grep -q '^\[volume\]' "${conf}"; then
      printf '\n[volume]\nmount_on_startup=0\nmount_removable=0\nautorun=0\n' | sudo tee -a "${conf}" >/dev/null
    else
      sudo sed -i \
        -e 's/^mount_on_startup=.*/mount_on_startup=0/' \
        -e 's/^mount_removable=.*/mount_removable=0/' \
        -e 's/^autorun=.*/autorun=0/' \
        "${conf}"
      sudo grep -q '^mount_on_startup=' "${conf}" || sudo sed -i '/^\[volume\]/a mount_on_startup=0' "${conf}"
      sudo grep -q '^mount_removable=' "${conf}" || sudo sed -i '/^\[volume\]/a mount_removable=0' "${conf}"
      sudo grep -q '^autorun=' "${conf}" || sudo sed -i '/^\[volume\]/a autorun=0' "${conf}"
    fi
    echo "pcmanfm system: ${conf}"
  done < <(find /etc/xdg/pcmanfm -type f -name 'pcmanfm.conf' -print0 2>/dev/null)
fi

# GNOME/gvfs media-handling keys (present on some Pi images; ignore if missing).
if command -v gsettings >/dev/null 2>&1; then
  gsettings set org.gnome.desktop.media-handling automount false 2>/dev/null || true
  gsettings set org.gnome.desktop.media-handling automount-open false 2>/dev/null || true
  gsettings set org.gnome.desktop.media-handling autorun-never true 2>/dev/null || true
  echo "gsettings: media-handling automount/open disabled (if schema exists)"
fi

# Reload desktop file manager so volume settings apply without full reboot.
if pgrep -x pcmanfm >/dev/null 2>&1; then
  # Preserve desktop wallpaper manager: restart with same profile if detectable.
  _pf=""
  _cmd=$(tr '\0' ' ' </proc/"$(pgrep -n -x pcmanfm)"/cmdline 2>/dev/null || true)
  # Avoid [[ =~ ]] char-class quirks on Pi bash — parse --profile=X / --profile X.
  case " ${_cmd} " in
    *" --profile="*)
      _pf="${_cmd#*--profile=}"
      _pf="${_pf%% *}"
      ;;
    *" --profile "*)
      _pf="${_cmd#*--profile }"
      _pf="${_pf%% *}"
      ;;
  esac
  killall pcmanfm 2>/dev/null || true
  sleep 0.5
  if [[ -n "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]]; then
    if [[ -n "${_pf}" ]]; then
      nohup pcmanfm --desktop --profile "${_pf}" >/dev/null 2>&1 &
      echo "restarted pcmanfm --desktop --profile ${_pf}"
    else
      nohup pcmanfm --desktop >/dev/null 2>&1 &
      echo "restarted pcmanfm --desktop"
    fi
  else
    echo "pcmanfm killed (no DISPLAY/WAYLAND — will restart at next login)"
  fi
fi

# ---------------------------------------------------------------------------
# WiFi password dialog — disable nm-applet secret agent UI
# ---------------------------------------------------------------------------
_hide_autostart() {
  local name=$1
  local dest="${AUTOSTART}/${name}"
  cat >"${dest}" <<EOF
[Desktop Entry]
Type=Application
Name=${name%.desktop}
Hidden=true
X-GNOME-Autostart-enabled=false
EOF
  echo "autostart hidden: ${dest}"
}

_hide_autostart "nm-applet.desktop"
_hide_autostart "nm-applet-autostart.desktop"
_hide_autostart "org.gnome.nm-applet.desktop"
_hide_autostart "nm-tray.desktop"

# labwc (Pi OS Trixie+) — autostart is a shell script, not xdg desktop files.
_silence_labwc_nm() {
  local dest="${HOME_DIR}/.config/labwc/autostart"
  mkdir -p "$(dirname "${dest}")"
  if [[ ! -f "${dest}" && -f /etc/xdg/labwc/autostart ]]; then
    cp -a /etc/xdg/labwc/autostart "${dest}"
  fi
  [[ -f "${dest}" ]] || return 0
  if grep -qE '^[[:space:]]*(nm-applet|nm-tray)\b' "${dest}"; then
    sed -i -E 's/^[[:space:]]*(nm-applet|nm-tray)\b/# \1  # disabled by harden_pi_desktop.sh/' "${dest}"
    echo "labwc: commented nm-applet in ${dest}"
  fi
}
_silence_labwc_nm

# wayfire — comment autostart lines that launch nm-applet (user config only).
_silence_wayfire_nm() {
  local dest=$1
  [[ -f "${dest}" ]] || return 0
  if grep -qE '^[[:space:]]*[^#=]+=.*nm-applet' "${dest}"; then
    sed -i -E 's/^([[:space:]]*[^#=]+=.*nm-applet)/# \1  # disabled by harden_pi_desktop.sh/' "${dest}"
    echo "wayfire: commented nm-applet in ${dest}"
  fi
}
_silence_wayfire_nm "${HOME_DIR}/.config/wayfire.ini"

_silence_lxsession_nm() {
  local src=$1
  local dest=$2
  [[ -f "${src}" ]] || return 0
  mkdir -p "$(dirname "${dest}")"
  if [[ ! -f "${dest}" ]]; then
    cp -a "${src}" "${dest}"
  fi
  if grep -qE '^@nm-applet' "${dest}"; then
    sed -i 's/^@nm-applet/# @nm-applet  # disabled by harden_pi_desktop.sh/' "${dest}"
    echo "lxsession: commented @nm-applet in ${dest}"
  fi
}

_silence_lxsession_nm \
  "/etc/xdg/lxsession/LXDE-pi/autostart" \
  "${HOME_DIR}/.config/lxsession/LXDE-pi/autostart"
_silence_lxsession_nm \
  "/etc/xdg/lxsession/LXDE/autostart" \
  "${HOME_DIR}/.config/lxsession/LXDE/autostart"

if pgrep -x nm-applet >/dev/null 2>&1 || pgrep -x nm-tray >/dev/null 2>&1; then
  killall nm-applet nm-tray 2>/dev/null || true
  echo "killed running nm-applet/nm-tray"
fi

# ---------------------------------------------------------------------------
# Store WiFi PSK as system secrets (no interactive agent needed to reconnect)
# ---------------------------------------------------------------------------
if command -v nmcli >/dev/null 2>&1; then
  mapfile -t WIFI_CONNS < <(nmcli -t -f NAME,TYPE connection show 2>/dev/null | awk -F: '$2=="802-11-wireless"{print $1}')
  if [[ ${#WIFI_CONNS[@]} -eq 0 ]]; then
    echo "nmcli: no WiFi connections found (skip secret migration)"
  else
    for cname in "${WIFI_CONNS[@]}"; do
      echo "nmcli: systemize secrets for '${cname}'"
      sudo nmcli connection modify "${cname}" \
        connection.permissions "" \
        802-11-wireless-security.psk-flags 0 \
        connection.autoconnect yes \
        connection.autoconnect-retries 0 \
        2>/dev/null || echo "WARN: could not modify '${cname}' (may need interactive sudo once)" >&2
    done
    sudo nmcli connection reload 2>/dev/null || true
  fi
else
  echo "nmcli: not installed — skip WiFi secret migration"
fi

echo ""
echo "Done."
echo "USB: libfm autorun=0 + pcmanfm volume off (user + /etc/xdg); pcmanfm reloaded if running."
echo "WiFi: nm-applet hidden (LXDE + labwc + wayfire); PSKs marked system-stored."
echo "Re-insert the USB stick to verify — no 'Removable medium is inserted' dialog."
echo "If wallpaper/desktop icons vanished, log out/in once (or reboot)."

# Pi HS OUT idle low on every board (older HAT: pads unconnected; Rev E+: never high-Z).
_hs_idle=""
for _c in \
  "${HOME_DIR}/EtherGold/sync/install_hs_out_idle.sh" \
  "${HOME_DIR}/DyzineFrame/sync/install_hs_out_idle.sh"
do
  if [[ -f "${_c}" ]]; then
    _hs_idle="${_c}"
    break
  fi
done
if [[ -n "${_hs_idle}" ]]; then
  echo "HS OUT idle: ${_hs_idle}"
  mkdir -p "${HOME_DIR}/DyzineFrame/log"
  timeout 20 bash "${_hs_idle}" >>"${HOME_DIR}/DyzineFrame/log/harden_pi_desktop.log" 2>&1 || \
    echo "WARN: HS OUT idle install failed (need sudo -n pinctrl)" >&2
else
  echo "HS OUT idle: installer not found — skip"
fi
