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

SERVICE_NAME="its-a-plane"
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SERVICE_USER="${SUDO_USER:-admin}"
INSTALL_DIR=""
SKIP_APT=0
SKIP_RGB_CHECK=0
INSTALL_RGB_MATRIX=0
SKIP_SWAP_SETUP=0
NO_START=0

usage() {
  cat <<'EOF'
Usage: sudo bash tools/factory_install.sh [options]

Options:
  --user USER             Service account (default: SUDO_USER or admin)
  --install-dir PATH      Application path (default: /home/USER/its-a-plane-python)
  --skip-apt              Do not install operating-system packages
  --install-rgb-matrix    Build the official RGB matrix Python binding
  --skip-swap-setup       Do not increase swap on low-memory Pis
  --skip-rgb-check        Allow installation without the rgbmatrix Python binding
  --no-start              Install and enable the service without starting it
  -h, --help              Show this help

Run this from an extracted, sanitized Plane Tracker release ZIP.
EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --user) SERVICE_USER="$2"; shift 2 ;;
    --install-dir) INSTALL_DIR="$2"; shift 2 ;;
    --skip-apt) SKIP_APT=1; shift ;;
    --install-rgb-matrix) INSTALL_RGB_MATRIX=1; shift ;;
    --skip-swap-setup) SKIP_SWAP_SETUP=1; shift ;;
    --skip-rgb-check) SKIP_RGB_CHECK=1; shift ;;
    --no-start) NO_START=1; shift ;;
    -h|--help) usage; exit 0 ;;
    *) echo "Unknown option: $1" >&2; usage >&2; exit 2 ;;
  esac
done

if [[ $EUID -ne 0 ]]; then
  echo "Run this installer with sudo." >&2
  exit 1
fi

if ! id "$SERVICE_USER" >/dev/null 2>&1; then
  echo "Service user '$SERVICE_USER' does not exist." >&2
  exit 1
fi

USER_HOME="$(getent passwd "$SERVICE_USER" | cut -d: -f6)"
INSTALL_DIR="${INSTALL_DIR:-$USER_HOME/its-a-plane-python}"

if [[ ! -f "$SOURCE_DIR/its-a-plane.py" ]]; then
  echo "The release payload is incomplete: its-a-plane.py was not found." >&2
  exit 1
fi

echo "Installing Plane Tracker"
echo "  Source:  $SOURCE_DIR"
echo "  Target:  $INSTALL_DIR"
echo "  User:    $SERVICE_USER"

if [[ $SKIP_APT -eq 0 ]]; then
  export DEBIAN_FRONTEND=noninteractive
  apt-get update
  apt-get install -y \
    network-manager iw wireless-tools sqlite3 rsync sudo unzip git dphys-swapfile \
    python3 python3-dev python3-pip python3-venv cython3 \
    build-essential cmake ninja-build libjpeg-dev zlib1g-dev
fi

if [[ $SKIP_SWAP_SETUP -eq 0 ]]; then
  memory_kib="$(awk '/^MemTotal:/{print $2}' /proc/meminfo)"
  swap_kib="$(awk '/^SwapTotal:/{print $2}' /proc/meminfo)"
  memory_kib="${memory_kib:-0}"
  swap_kib="${swap_kib:-0}"

  if (( memory_kib > 0 && memory_kib < 1048576 && swap_kib < 900000 )); then
    if ! command -v dphys-swapfile >/dev/null 2>&1; then
      echo "Low-memory Pi detected, but dphys-swapfile is unavailable." >&2
      echo "Install dphys-swapfile or rerun without --skip-apt." >&2
      exit 1
    fi

    echo "Low-memory Pi detected; configuring 1 GB swap."
    dphys-swapfile swapoff >/dev/null 2>&1 || true
    if grep -q '^CONF_SWAPSIZE=' /etc/dphys-swapfile; then
      sed -i 's/^CONF_SWAPSIZE=.*/CONF_SWAPSIZE=1024/' /etc/dphys-swapfile
    else
      printf '\nCONF_SWAPSIZE=1024\n' >> /etc/dphys-swapfile
    fi
    dphys-swapfile setup
    dphys-swapfile swapon
    swap_kib="$(awk '/^SwapTotal:/{print $2}' /proc/meminfo)"
    echo "Swap available: $((swap_kib / 1024)) MiB"
  fi
fi

systemctl enable --now NetworkManager.service

mkdir -p "$INSTALL_DIR"
if [[ "$SOURCE_DIR" != "$INSTALL_DIR" ]]; then
  rsync -a --delete \
    --exclude config \
    --exclude data \
    --exclude .cache \
    --exclude .updates \
    --exclude dist \
    "$SOURCE_DIR/" "$INSTALL_DIR/"
fi

mkdir -p \
  "$INSTALL_DIR/config" \
  "$INSTALL_DIR/data" \
  "$INSTALL_DIR/.cache" \
  "$INSTALL_DIR/.updates"

python3 -m venv --system-site-packages "$INSTALL_DIR/.venv"
"$INSTALL_DIR/.venv/bin/python" -m pip install --upgrade pip wheel
"$INSTALL_DIR/.venv/bin/python" -m pip install -r "$INSTALL_DIR/requirements.txt"

if [[ $INSTALL_RGB_MATRIX -eq 1 ]] && \
   ! "$INSTALL_DIR/.venv/bin/python" -c "import rgbmatrix" >/dev/null 2>&1; then
  RGB_MATRIX_SOURCE="/opt/rpi-rgb-led-matrix"
  if [[ ! -d "$RGB_MATRIX_SOURCE/.git" ]]; then
    git clone --depth 1 \
      https://github.com/hzeller/rpi-rgb-led-matrix.git \
      "$RGB_MATRIX_SOURCE"
  fi
  CMAKE_BUILD_PARALLEL_LEVEL=1 \
    "$INSTALL_DIR/.venv/bin/python" -m pip install "$RGB_MATRIX_SOURCE"
fi

if ! "$INSTALL_DIR/.venv/bin/python" -c "import rgbmatrix" >/dev/null 2>&1; then
  if [[ $SKIP_RGB_CHECK -eq 0 ]]; then
    cat >&2 <<'EOF'
The rgbmatrix Python binding is not installed.

Rerun this installer with --install-rgb-matrix, or install
hzeller/rpi-rgb-led-matrix and its Python binding manually. Official details:
https://github.com/hzeller/rpi-rgb-led-matrix/tree/master/bindings/python
EOF
    exit 1
  fi
  echo "WARNING: rgbmatrix is missing; the display service will not start."
fi

for group in gpio spi; do
  if getent group "$group" >/dev/null; then
    usermod -aG "$group" "$SERVICE_USER"
  fi
done

serial="$(awk -F: '/^Serial/{gsub(/[[:space:]]/,"",$2); print $2}' /proc/cpuinfo | tail -1)"
serial="${serial:-$(hostname)}"
suffix="${serial: -8}"
setup_password="plane${suffix}"

cat > /etc/default/its-a-plane <<EOF
ITS_A_PLANE_SETUP_WIFI_PASSWORD=$setup_password
EOF
chmod 600 /etc/default/its-a-plane

sed \
  -e "s|@SERVICE_USER@|$SERVICE_USER|g" \
  -e "s|@INSTALL_DIR@|$INSTALL_DIR|g" \
  "$INSTALL_DIR/deploy/its-a-plane.service" \
  > "/etc/systemd/system/$SERVICE_NAME.service"

nmcli_path="$(command -v nmcli)"
iw_path="$(command -v iw || true)"
iwlist_path="$(command -v iwlist || true)"
cat > "/etc/sudoers.d/$SERVICE_NAME" <<EOF
$SERVICE_USER ALL=(root) NOPASSWD: $nmcli_path
$SERVICE_USER ALL=(root) NOPASSWD: /bin/systemctl restart $SERVICE_NAME
$SERVICE_USER ALL=(root) NOPASSWD: /bin/systemctl restart $SERVICE_NAME.service
EOF
if [[ -n "$iw_path" ]]; then
  echo "$SERVICE_USER ALL=(root) NOPASSWD: $iw_path" >> "/etc/sudoers.d/$SERVICE_NAME"
fi
if [[ -n "$iwlist_path" ]]; then
  echo "$SERVICE_USER ALL=(root) NOPASSWD: $iwlist_path" >> "/etc/sudoers.d/$SERVICE_NAME"
fi
chmod 440 "/etc/sudoers.d/$SERVICE_NAME"
visudo -cf "/etc/sudoers.d/$SERVICE_NAME"

chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
systemctl daemon-reload
systemctl enable "$SERVICE_NAME.service"

sudo -u "$SERVICE_USER" \
  "$INSTALL_DIR/.venv/bin/python" \
  "$INSTALL_DIR/tools/factory_check.py" \
  --install-dir "$INSTALL_DIR"

if [[ $NO_START -eq 0 ]]; then
  systemctl restart "$SERVICE_NAME.service"
fi

cat <<EOF

Plane Tracker factory installation complete.

Setup Wi-Fi:
  SSID:     PlaneTracker-Setup-XXXXXX
  Password: $setup_password
  Page:     http://10.42.0.1:8080/wifi-setup

Record the password on the device label before shipping.
EOF
