#!/bin/bash
# alpha-webengine — install / enable / disable / remove web servers from the panel.
# Root-owned; called by www-data via NOPASSWD sudoers. SAFETY:
#   - never stops/removes nginx (it serves the panel);
#   - apt-installable alternatives (caddy/lighttpd/haproxy) bind :80/:443 which
#     nginx already holds, so they are installed but NOT started (policy-rc.d), and
#     left disabled — the admin reconfigures ports before enabling;
#   - JVM/binary-only engines (traefik) are refused (guided manual).
set -eu
ACTION="${1:-}"; ENGINE="${2:-}"
LOG=/var/log/alpha-webengine.log
[[ "$ENGINE" =~ ^[a-z]+$ ]] || { echo "BAD_ENGINE: $ENGINE"; exit 2; }

svc_of() { case "$1" in nginx) echo nginx;; apache) echo apache2;; openlitespeed) [ -f /lib/systemd/system/lshttpd.service ] && echo lshttpd || echo lsws;; caddy) echo caddy;; lighttpd) echo lighttpd;; haproxy) echo haproxy;; traefik) echo traefik;; *) echo "";; esac; }
pkg_of() { case "$1" in apache) echo apache2;; caddy) echo caddy;; lighttpd) echo lighttpd;; haproxy) echo haproxy;; *) echo "";; esac; }

case "$ACTION" in
  enable|disable)
    [ "$ENGINE" = nginx ] && [ "$ACTION" = disable ] && { echo "PROTECTED: nginx serves the panel"; exit 4; }
    SVC=$(svc_of "$ENGINE")
    [ -n "$SVC" ] || { echo "NO_SERVICE: $ENGINE has no manageable service"; exit 3; }
    systemctl list-unit-files "${SVC}.service" 2>/dev/null | grep -q "$SVC" || { echo "NOT_INSTALLED: $ENGINE"; exit 5; }
    if [ "$ACTION" = enable ]; then
      systemctl enable --now "$SVC" >/dev/null 2>&1 && echo "OK: $ENGINE enabled + started" || echo "FAILED: $ENGINE did not start (port :80/:443 likely held by nginx — reconfigure its ports)"
    else systemctl disable --now "$SVC" >/dev/null 2>&1 && echo "OK: $ENGINE disabled + stopped"; fi
    ;;
  install)
    case "$ENGINE" in
      nginx) echo "OK: nginx is already installed (the panel front)"; exit 0 ;;
      openlitespeed) echo "MANUAL: OpenLiteSpeed installs from repo.litespeed.sh — not in the base apt sources"; exit 7 ;;
      traefik) echo "MANUAL: Traefik ships as a single binary/container — install from traefik.io or Docker, not apt"; exit 7 ;;
      apache|caddy|lighttpd|haproxy)
        PKG=$(pkg_of "$ENGINE")
        dpkg-query -W -f='${db:Status-Abbrev}' "$PKG" 2>/dev/null | grep -q '^ii' && { echo "OK: $ENGINE already installed"; exit 0; }
        CAND=$(apt-cache policy "$PKG" 2>/dev/null | awk '/Candidate:/{print $2; exit}')
        { [ -n "$CAND" ] && [ "$CAND" != "(none)" ]; } || { echo "NO_CANDIDATE: $PKG is not available from apt on this system"; exit 6; }
        # install WITHOUT starting (policy-rc.d 101) so it can't fight nginx for :80,
        # then leave it disabled for the admin to configure a free port.
        setsid bash -c "{
          echo \"== \$(date -Is) install $ENGINE\"
          printf '#!/bin/sh\nexit 101\n' > /usr/sbin/policy-rc.d; chmod +x /usr/sbin/policy-rc.d
          DEBIAN_FRONTEND=noninteractive apt-get update -q || true
          DEBIAN_FRONTEND=noninteractive apt-get install -y -q $PKG
          RC=\$?
          rm -f /usr/sbin/policy-rc.d
          systemctl disable --now $(svc_of "$ENGINE") 2>/dev/null || true
          echo done rc=\$RC
        } >> $LOG 2>&1" </dev/null &
        echo "STARTED: installing $ENGINE (background; left stopped — nginx holds :80/:443, set a free port then Enable)" ;;
      *) echo "UNKNOWN_ENGINE: $ENGINE"; exit 1 ;;
    esac ;;
  remove)
    [ "$ENGINE" = nginx ] && { echo "PROTECTED: nginx serves the panel — cannot be removed here"; exit 4; }
    if [ "$ENGINE" = openlitespeed ]; then
      [ -d /usr/local/lsws ] || { echo "NOT_INSTALLED: OpenLiteSpeed"; exit 5; }
      setsid bash -c "{ echo \"== \$(date -Is) remove openlitespeed\"; systemctl disable --now lshttpd lsws 2>/dev/null; DEBIAN_FRONTEND=noninteractive apt-get purge -y -q openlitespeed 'lsphp*'; rm -rf /usr/local/lsws; echo done rc=\$?; } >> $LOG 2>&1" </dev/null &
      echo "STARTED: removing OpenLiteSpeed (background)"; exit 0
    fi
    PKG=$(pkg_of "$ENGINE")
    [ -n "$PKG" ] || { echo "NOT_REMOVABLE: $ENGINE is not an apt-managed server here"; exit 5; }
    dpkg-query -W -f='${db:Status-Abbrev}' "$PKG" 2>/dev/null | grep -q '^ii' || { echo "NOT_INSTALLED: $ENGINE"; exit 5; }
    setsid bash -c "{ echo \"== \$(date -Is) remove $ENGINE\"; systemctl disable --now $(svc_of "$ENGINE") 2>/dev/null; DEBIAN_FRONTEND=noninteractive apt-get purge -y -q $PKG; DEBIAN_FRONTEND=noninteractive apt-get autoremove -y -q; echo done rc=\$?; } >> $LOG 2>&1" </dev/null &
    echo "STARTED: removing $ENGINE (background)" ;;
  *) echo "BAD_ACTION: $ACTION"; exit 1 ;;
esac
