#!/usr/bin/env bash
###############################################################################
# amsoil-pm2-reload - root-owned PM2 reload wrapper for deploy automation
#
# SECURITY: the deploy user can write every file in the app directory, so
# sudoers must never point into the deploy tree. Install this file OUTSIDE
# the repo, as root, and reference only that copy:
#
#   sudo install -o root -g root -m 0755 \
#     scripts/server/pm2-reload-wrapper.sh /usr/local/sbin/amsoil-pm2-reload
#
# Then whitelist exactly the argument(s) valid on that box, via
# `visudo -f /etc/sudoers.d/amsoil-deploy`:
#
#   dev box:
#     acdev3 ALL=(root) NOPASSWD: /usr/local/sbin/amsoil-pm2-reload dev
#   staging/production box:
#     amsoildlp ALL=(root) NOPASSWD: /usr/local/sbin/amsoil-pm2-reload staging, /usr/local/sbin/amsoil-pm2-reload production
#
# Re-install manually and deliberately when this template changes. Never
# automate copying from the repo into /usr/local/sbin.
###############################################################################
set -euo pipefail

if [ "$(id -u)" -ne 0 ]; then
  echo "amsoil-pm2-reload: must run as root (invoke via the sudoers rule)" >&2
  exit 3
fi

case "${1:-}" in
  dev)        APP_DIR=/home/acdev3/amsoil-dlp.acdev3.com;              CLEAR_DEV_CACHE=true ;;
  staging)    APP_DIR=/home/amsoildlp/public_html/aimclear.biz;        CLEAR_DEV_CACHE=false ;;
  production) APP_DIR=/home/amsoildlp/public_html/amsoil.aimclear.com; CLEAR_DEV_CACHE=false ;;
  *)
    echo "usage: amsoil-pm2-reload <dev|staging|production>" >&2
    exit 2
    ;;
esac

# sudo -n runs under sudoers secure_path, which may not include pm2's
# install location even though root's interactive shell finds it. Prepend
# the common global-npm locations, then fail with an actionable message.
if ! command -v pm2 >/dev/null 2>&1; then
  export PATH="/usr/local/bin:/usr/local/sbin:$PATH"
fi
if ! command -v pm2 >/dev/null 2>&1; then
  echo "amsoil-pm2-reload: pm2 not found on PATH ($PATH)." >&2
  echo "Install pm2 system-wide, or hardcode its absolute path in this wrapper." >&2
  exit 4
fi

cd "$APP_DIR"

# Dev runs `next dev` (Turbopack), whose persistent cache in .next corrupts
# when the server dies mid-compile - e.g. next dev's own restart on a
# deploy-rewritten next.config.mjs racing this reload. A live reload onto a
# poisoned cache then panics on every compile. So on dev: stop the app,
# clear the cache while nothing is running, and start fresh; next dev
# recompiles on demand (first request after a deploy takes a few seconds).
# NEVER do this on staging/production - there .next is the `next build`
# output actually being served.
if [ "$CLEAR_DEV_CACHE" = true ]; then
  pm2 stop ecosystem.config.js \
    || echo "amsoil-pm2-reload: pm2 stop reported an error; verifying nothing is still running" >&2

  # Fail CLOSED: only clear the cache once nothing from this tree is running.
  # pm2 stop can fail benignly (app not registered yet, e.g. after a reboot)
  # or seriously (daemon unreachable while next dev is still alive). Testing
  # the actual hazard distinguishes the two. Matches the server and its
  # children (Turbopack's postcss workers run from under .next). The short
  # loop lets just-killed children finish exiting.
  for _ in 1 2 3 4 5; do
    pgrep -f "$APP_DIR/(node_modules|\.next)" >/dev/null || break
    sleep 1
  done
  if pgrep -f "$APP_DIR/(node_modules|\.next)" >/dev/null; then
    echo "amsoil-pm2-reload: refusing to clear .next: processes from $APP_DIR are still running:" >&2
    pgrep -af "$APP_DIR/(node_modules|\.next)" >&2 || true
    exit 5
  fi

  rm -rf "$APP_DIR/.next"
fi

pm2 startOrReload ecosystem.config.js --update-env
pm2 save
