#!/bin/bash
# orbvis-setup – manage OrbVis installation
#
# Commands (run as the OMD site user):
#   orbvis-setup           – install / upgrade OrbVis
#   orbvis-setup uninstall – remove OrbVis (boards and database are kept)
#
set -euo pipefail

BOLD='\033[1m'; GREEN='\033[0;32m'; YELLOW='\033[0;33m'; RED='\033[0;31m'; RESET='\033[0m'
step()  { echo -e "  ${BOLD}▸ $*${RESET}"; }
ok()    { echo -e "  ${GREEN}✓ $*${RESET}"; }
warn()  { echo -e "  ${YELLOW}⚠ $*${RESET}"; }
die()   { echo -e "\n${RED}Error: $*${RESET}\n" >&2; exit 1; }

SITE="${OMD_SITE:-}"
ROOT="${OMD_ROOT:-}"
[[ -z "$SITE" || -z "$ROOT" ]] && die "Run as the OMD site user (OMD_SITE / OMD_ROOT must be set).\nExample: su - <SITE> -c 'orbvis-setup'"

MKP_LIB="$ROOT/local/lib/orbvis"
ORBVIS_DIR="$ROOT/local/share/orbvis"
HTDOCS_DIR="$ORBVIS_DIR/htdocs"
BOARDS_DIR="$ORBVIS_DIR/boards"
ENV_FILE="$ORBVIS_DIR/.env"
CONNECTIONS_FILE="$ORBVIS_DIR/connections.json"
DB_FILE="$ORBVIS_DIR/orbvis.db"
VENV_DIR="$ORBVIS_DIR/venv"
APACHE_CONF="$ROOT/etc/apache/conf.d/orbvis.conf"
INIT_SCRIPT="$ROOT/etc/init.d/orbvis"
BACKEND_PORT=8420
LIVESTATUS_SOCKET="$ROOT/tmp/run/live"

CMD="${1:-setup}"

case "$CMD" in

# ---------------------------------------------------------------------------
uninstall)
# ---------------------------------------------------------------------------
  echo ""
  echo -e "${BOLD}OrbVis Uninstall${RESET}"
  echo "  Site: $SITE  ($ROOT)"
  echo ""

  step "Stopping OrbVis"
  omd stop orbvis 2>/dev/null || true
  ok "OrbVis stopped"

  step "Removing OMD service"
  rm -f "$ROOT/etc/rc.d/85-orbvis"
  rm -f "$INIT_SCRIPT"
  ok "OMD service removed"

  step "Removing Apache configuration"
  rm -f "$APACHE_CONF"
  omd reload apache
  ok "Apache configuration removed"

  step "Removing frontend and backend"
  rm -rf "$HTDOCS_DIR"
  rm -rf "$VENV_DIR"
  rm -rf "$MKP_LIB/server"
  ok "Frontend, venv and backend source removed"

  echo ""
  echo -e "${GREEN}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
  echo -e "${GREEN}${BOLD}  OrbVis uninstalled.${RESET}"
  echo -e "${GREEN}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
  echo ""
  echo "  Kept (user data):  $BOARDS_DIR"
  echo "                     $DB_FILE"
  echo "                     $ENV_FILE"
  echo "                     $CONNECTIONS_FILE"
  echo ""
  echo "  Remove manually if no longer needed:"
  echo "    rm -rf $ORBVIS_DIR"
  echo ""
  echo -e "  ${YELLOW}${BOLD}Next step: remove the MKP package from Checkmk:${RESET}"
  echo "    mkp disable orbvis"
  echo "    mkp remove orbvis"
  echo ""
  ;;

# ---------------------------------------------------------------------------
setup)
# ---------------------------------------------------------------------------
  [[ -d "$MKP_LIB" ]] || die "MKP library not found at $MKP_LIB\nDid you install the orbvis MKP first?"

  echo ""
  echo -e "${BOLD}OrbVis Post-Install Setup${RESET}"
  echo "  Site: $SITE  ($ROOT)"
  echo ""

  # 1. Frontend: extract pre-built tarball
  step "Deploying frontend"
  mkdir -p "$HTDOCS_DIR"
  rm -rf "${HTDOCS_DIR:?}"/*
  tar xzf "$MKP_LIB/htdocs.tar.gz" -C "$HTDOCS_DIR"
  ok "Frontend deployed to $HTDOCS_DIR"

  # 2. Backend source: extract tarball
  step "Extracting backend source"
  mkdir -p "$MKP_LIB/server"
  tar xzf "$MKP_LIB/server.tar.gz" -C "$MKP_LIB/server"
  ok "Backend source extracted"

  # 3. Boards directory — backend seeds bundled demos on first start
  # (gated by a .demo-seeded marker, so user deletions are honored)
  mkdir -p "$BOARDS_DIR/backgrounds"

  # 4. Python virtualenv + backend
  step "Setting up Python environment"

  # Resolve a Python 3.12+ interpreter. Order:
  #   1. PYTHON3 env var (lets users force a specific binary)
  #   2. $OMD_ROOT/bin/python3 (the site Python)
  #   3. python3.13, python3.12 on PATH (deadsnakes / OS package)
  #   4. python3 on PATH (last resort, may be too old)
  py_version_ok() {
    "$1" -c 'import sys; sys.exit(0 if sys.version_info >= (3, 12) else 1)' 2>/dev/null
  }

  PYTHON3="${PYTHON3:-}"
  if [[ -n "$PYTHON3" ]]; then
    [[ -x "$PYTHON3" ]] || die "PYTHON3=$PYTHON3 is not executable."
  else
    for _candidate in \
        "$ROOT/bin/python3" \
        "$(command -v python3.13 2>/dev/null || true)" \
        "$(command -v python3.12 2>/dev/null || true)" \
        "$(command -v python3 2>/dev/null || true)"; do
      [[ -n "$_candidate" && -x "$_candidate" ]] || continue
      if py_version_ok "$_candidate"; then
        PYTHON3="$_candidate"
        break
      fi
    done
  fi

  if [[ -z "$PYTHON3" ]] || ! py_version_ok "$PYTHON3"; then
    FOUND_VERSION="$("${PYTHON3:-python3}" --version 2>&1 || echo 'not found')"
    die "OrbVis requires Python 3.12 or newer.

  Found: $FOUND_VERSION
  Searched: \$PYTHON3, $ROOT/bin/python3, python3.13, python3.12, python3

  Install Python 3.12 and re-run orbvis-setup. On Debian/Ubuntu:
    sudo add-apt-repository ppa:deadsnakes/ppa
    sudo apt install python3.12 python3.12-venv

  Then point orbvis-setup at it explicitly:
    PYTHON3=/usr/bin/python3.12 orbvis-setup"
  fi
  ok "Using $($PYTHON3 --version) ($PYTHON3)"

  if [[ ! -d "$VENV_DIR" ]]; then
    "$PYTHON3" -m venv --copies "$VENV_DIR"
  fi
  step "Installing backend dependencies"
  "$VENV_DIR/bin/pip" install --quiet --upgrade pip
  "$VENV_DIR/bin/pip" install --quiet "$MKP_LIB/server"
  ok "Backend installed"

  # 5. Configuration
  step "Writing configuration"
  EXISTING_SECRET=""
  [[ -f "$ENV_FILE" ]] && EXISTING_SECRET=$(grep -E '^SECRET_KEY=' "$ENV_FILE" | head -1 | cut -d= -f2- || true)
  SECRET_KEY="${EXISTING_SECRET:-$("$PYTHON3" -c 'import secrets; print(secrets.token_hex(32))')}"

  cat > "$ENV_FILE" << EOF
BOARDS_DIR=$BOARDS_DIR
CONNECTIONS_FILE=$CONNECTIONS_FILE
DATABASE_URL=sqlite+aiosqlite:///$DB_FILE
SECRET_KEY=$SECRET_KEY
STATE_REFRESH_INTERVAL=15
CHECKMK_HTPASSWD=$ROOT/etc/htpasswd
CHECKMK_OMD_ROOT=$ROOT
CHECKMK_SITE=$SITE
EOF

  if [[ ! -f "$CONNECTIONS_FILE" ]]; then
    cat > "$CONNECTIONS_FILE" << EOF
[
  {
    "id": "live_1",
    "type": "livestatus",
    "label": "cmk $SITE",
    "socket_path": "$LIVESTATUS_SOCKET",
    "checkmk_url": "/$SITE/check_mk"
  }
]
EOF
    ok "Configuration written"
  else
    ok "Configuration written (existing connections.json kept)"
  fi

  # 6. Apache configuration
  step "Writing Apache configuration"

  # Locate mod_proxy.so — CMK 2.4 bundles its own, CMK 2.3 uses the system Apache binary
  # and therefore needs the system module path (Ubuntu/Debian: /usr/lib/apache2/modules/).
  PROXY_SO=""
  PROXY_HTTP_SO=""
  for _dir in \
      "$ROOT/lib/apache/modules" \
      "/usr/lib/apache2/modules" \
      "/usr/lib64/httpd/modules" \
      "/usr/lib/httpd/modules"; do
    if [[ -f "$_dir/mod_proxy.so" && -f "$_dir/mod_proxy_http.so" ]]; then
      PROXY_SO="$_dir/mod_proxy.so"
      PROXY_HTTP_SO="$_dir/mod_proxy_http.so"
      break
    fi
  done

  if [[ -z "$PROXY_SO" ]]; then
    warn "mod_proxy.so not found — API proxy will be disabled. Backend API will be unreachable."
  fi

  cat > "$APACHE_CONF" << EOF
# OrbVis – static frontend + backend proxy
# Auto-generated by orbvis-setup

# mod_proxy is not bundled in all OMD versions — load from detected path
<IfModule !mod_proxy.c>
    LoadModule proxy_module $PROXY_SO
</IfModule>
<IfModule !mod_proxy_http.c>
    LoadModule proxy_http_module $PROXY_HTTP_SO
</IfModule>

Alias /$SITE/orbvis $HTDOCS_DIR

<Location /$SITE/orbvis>
    AuthType None
    Require all granted
</Location>

<Directory $HTDOCS_DIR>
    Options -Indexes +FollowSymLinks
    AllowOverride None
    Require all granted
    FallbackResource /$SITE/orbvis/index.html
</Directory>

<Location /$SITE/orbvis/api>
    ProxyPass        http://127.0.0.1:$BACKEND_PORT/api
    ProxyPassReverse http://127.0.0.1:$BACKEND_PORT/api
</Location>

<Location /$SITE/orbvis/images>
    ProxyPass        http://127.0.0.1:$BACKEND_PORT/images
    ProxyPassReverse http://127.0.0.1:$BACKEND_PORT/images
</Location>

<Location /$SITE/orbvis/boards/backgrounds>
    ProxyPass        http://127.0.0.1:$BACKEND_PORT/boards/backgrounds
    ProxyPassReverse http://127.0.0.1:$BACKEND_PORT/boards/backgrounds
</Location>
EOF
  ok "Apache configuration written"

  # 7. OMD init script
  step "Registering OrbVis as OMD service"
  cat > "$INIT_SCRIPT" << EOF
#!/bin/bash
# OMD init script for OrbVis backend

PIDFILE="\$OMD_ROOT/tmp/run/orbvis.pid"
LOGFILE="\$OMD_ROOT/var/log/orbvis.log"
VENV="$VENV_DIR"
PORT=$BACKEND_PORT
ENV_FILE="$ENV_FILE"

case "\$1" in
  start)
    if [[ -f "\$PIDFILE" ]] && kill -0 "\$(cat "\$PIDFILE")" 2>/dev/null; then
      echo "orbvis already running (pid \$(cat "\$PIDFILE"))"
      exit 0
    fi
    echo -n "Starting orbvis..."
    set -a; source "\$ENV_FILE"; set +a
    cd "$MKP_LIB/server"  # extracted by orbvis-setup step 2
    "\$VENV/bin/python3" -m alembic upgrade head >> "\$LOGFILE" 2>&1
    "\$VENV/bin/uvicorn" app.main:app \\
      --host 127.0.0.1 --port \$PORT \\
      --log-level warning \\
      >> "\$LOGFILE" 2>&1 &
    echo \$! > "\$PIDFILE"
    echo " OK (pid \$(cat "\$PIDFILE"))"
    ;;
  stop)
    if [[ -f "\$PIDFILE" ]]; then
      PID="\$(cat "\$PIDFILE")"
      if kill -0 "\$PID" 2>/dev/null; then
        echo -n "Stopping orbvis (pid \$PID)..."
        kill "\$PID"
        for _ in \$(seq 1 20); do kill -0 "\$PID" 2>/dev/null || break; sleep 0.5; done
        echo " OK"
      fi
      rm -f "\$PIDFILE"
    else
      echo "orbvis not running"
    fi
    ;;
  restart) \$0 stop; \$0 start ;;
  status)
    if [[ -f "\$PIDFILE" ]] && kill -0 "\$(cat "\$PIDFILE")" 2>/dev/null; then
      echo "orbvis running (pid \$(cat "\$PIDFILE"))"; exit 0
    else
      echo "orbvis not running"; exit 1
    fi
    ;;
  *) echo "Usage: \$0 {start|stop|restart|status}"; exit 1 ;;
esac
EOF
  chmod +x "$INIT_SCRIPT"
  ln -sf "$INIT_SCRIPT" "$ROOT/etc/rc.d/85-orbvis" 2>/dev/null || true
  ok "OrbVis registered as OMD service"

  # 8. Start services
  step "Reloading Apache"
  omd reload apache
  ok "Apache reloaded"

  step "Starting OrbVis"
  omd restart orbvis
  ok "OrbVis started"

  HOST="$(hostname -f 2>/dev/null || hostname)"
  echo ""
  echo -e "${GREEN}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
  echo -e "${GREEN}${BOLD}  OrbVis setup complete!${RESET}"
  echo -e "${GREEN}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
  echo ""
  echo "  Open in browser:  http://$HOST/$SITE/orbvis/"
  echo ""
  ;;

*)
  die "Unknown command: $CMD\nUsage: orbvis-setup [setup|uninstall]"
  ;;

esac
