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

BASE_URL="${REFUGEBOT_MONITOR_BASE_URL:-https://refugebot.com/downloads/refugebot-monitor}"
VERSION="${REFUGEBOT_MONITOR_VERSION:-}"
SERVICE_USER="${REFUGEBOT_MONITOR_USER:-${SUDO_USER:-}}"
BIN="/usr/local/bin/refugebot-monitor"
CONFIG_DIR="/etc/refugebot-monitor"
CONFIG="$CONFIG_DIR/monitor.yaml"

if [[ ${EUID:-$(id -u)} -ne 0 ]]; then
  echo "Run this installer with sudo." >&2
  exit 1
fi
if [[ $(uname -m) != "x86_64" ]]; then
  echo "RefugeBot Monitor currently supports x86-64 Linux hosts." >&2
  exit 1
fi
if ! command -v systemctl >/dev/null 2>&1; then
  echo "This installer needs a systemd-based Linux distribution." >&2
  exit 1
fi

if command -v apt-get >/dev/null 2>&1; then
  apt-get update -qq
  DEBIAN_FRONTEND=noninteractive apt-get install -y -qq ca-certificates curl tar sudo lib32gcc-s1
elif command -v dnf >/dev/null 2>&1; then
  dnf install -y ca-certificates curl tar sudo glibc.i686 libstdc++.i686
else
  echo "Install curl, tar, CA certificates, and the 32-bit glibc/libgcc runtime, then run this installer again." >&2
  exit 1
fi

if [[ -z "$SERVICE_USER" || "$SERVICE_USER" == "root" ]]; then
  SERVICE_USER="refugebot-monitor"
  if ! id "$SERVICE_USER" >/dev/null 2>&1; then
    useradd --system --create-home --home-dir /var/lib/refugebot-monitor --shell /usr/sbin/nologin "$SERVICE_USER"
  fi
fi
if ! id "$SERVICE_USER" >/dev/null 2>&1; then
  echo "Linux user '$SERVICE_USER' does not exist." >&2
  exit 1
fi
if [[ ! "$SERVICE_USER" =~ ^[A-Za-z_][A-Za-z0-9_-]*[$]?$ ]]; then
  echo "The Monitor service user name is not safe for the restricted updater rule." >&2
  exit 1
fi

BASE_URL="${BASE_URL%/}"
if [[ -z "$VERSION" ]]; then
  VERSION="$(curl -fsSL "$BASE_URL/latest.txt" | tr -d '\r\n')"
fi
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][A-Za-z0-9.]+)?$ ]]; then
  echo "The published monitor version is not valid." >&2
  exit 1
fi

if systemctl is-active --quiet refugebot-monitor.service; then
  current="$($BIN version 2>/dev/null || true)"
  if [[ "$current" == "$VERSION" ]]; then
    echo "RefugeBot Monitor $VERSION is already installed and running."
    exit 0
  fi
  echo "RefugeBot Monitor is running. Stop it during a planned maintenance window before upgrading." >&2
  exit 1
fi

work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
release_url="$BASE_URL/releases/$VERSION"
archive_name="refugebot-monitor-$VERSION-linux-amd64.tar.gz"
curl -fsSL "$release_url/$archive_name" -o "$work/$archive_name"
curl -fsSL "$release_url/SHA256SUMS.txt" -o "$work/SHA256SUMS.txt"
(cd "$work" && tr -d '\r' < SHA256SUMS.txt | grep "  $archive_name\$" | sha256sum -c -)
mkdir -p "$work/stage"
tar -xzf "$work/$archive_name" -C "$work/stage"
source_bin="$(find "$work/stage" -type f -name refugebot-monitor-linux-amd64 -print -quit)"
source_updater="$(find "$work/stage" -type f -name update.sh -print -quit)"
if [[ -z "$source_bin" || -z "$source_updater" ]]; then
  echo "The monitor executable or verified updater is missing from the published package." >&2
  exit 1
fi
chmod 0755 "$source_bin"
if [[ "$($source_bin version)" != "$VERSION" ]]; then
  echo "The package version does not match $VERSION." >&2
  exit 1
fi
install -m 0755 "$source_bin" "$BIN"
install -d -m 0755 /usr/local/libexec
install -m 0755 "$source_updater" /usr/local/libexec/refugebot-monitor-update
install -d -m 0750 -o "$SERVICE_USER" -g "$(id -gn "$SERVICE_USER")" "$CONFIG_DIR" /opt/refugebot

sudoers_temp="$work/refugebot-monitor-update.sudoers"
printf '%s ALL=(root) NOPASSWD: /usr/local/libexec/refugebot-monitor-update\n' "$SERVICE_USER" > "$sudoers_temp"
chmod 0440 "$sudoers_temp"
if command -v visudo >/dev/null 2>&1; then
  visudo -cf "$sudoers_temp" >/dev/null
fi
install -m 0440 "$sudoers_temp" /etc/sudoers.d/refugebot-monitor-update

if [[ ! -f "$CONFIG" ]]; then
  echo "RefugeBot Monitor is optional when your host already provides monitoring and restarts."
  echo "Setup is private to this server. From your computer, open another terminal and run:"
  echo "  ssh -L 8787:127.0.0.1:8787 $(logname 2>/dev/null || echo user)@$(hostname -f 2>/dev/null || hostname)"
  echo "Then open http://127.0.0.1:8787/ in your browser."
  systemctl stop refugebot-monitor-setup.service >/dev/null 2>&1 || true
  systemd-run --collect --unit=refugebot-monitor-setup --uid="$SERVICE_USER" --property="WorkingDirectory=$CONFIG_DIR" "$BIN" --config "$CONFIG" --setup-listen 127.0.0.1:8787 setup >/dev/null
  deadline=$((SECONDS + 1800))
  while [[ ! -f "$CONFIG" && $SECONDS -lt $deadline ]] && systemctl is-active --quiet refugebot-monitor-setup.service; do
    sleep 2
  done
  systemctl stop refugebot-monitor-setup.service >/dev/null 2>&1 || true
  if [[ ! -f "$CONFIG" ]]; then
    echo "Setup did not finish. Run the installer again; downloaded server files will be preserved." >&2
    exit 1
  fi
fi

chown "$SERVICE_USER:$(id -gn "$SERVICE_USER")" "$CONFIG"
chmod 0600 "$CONFIG"
cat > /etc/systemd/system/refugebot-monitor.service <<EOF
[Unit]
Description=RefugeBot 7DTD Monitor
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=$SERVICE_USER
WorkingDirectory=$CONFIG_DIR
ExecStart=$BIN --config $CONFIG run
Restart=on-failure
RestartSec=5s
UMask=0077
LimitNOFILE=65536
KillMode=process
TimeoutStopSec=150s

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now refugebot-monitor.service
echo "RefugeBot Monitor $VERSION is installed and running."
echo "Use an SSH tunnel to open http://127.0.0.1:8787/. Game ports still need firewall and router forwarding; the dashboard includes a port guide."
echo "Docker is not required or installed. The dashboard Update Center uses one exact root helper command; it cannot run arbitrary sudo commands."
