#!/usr/bin/env bash
#
# petav3 — environment verification & debug healthcheck
# ----------------------------------------------------------------------------
# Runs a battery of checks against everything server-setup.sh installs and
# prints a PASS/FAIL line for each, plus a final summary. Exit code is non-zero
# if any check fails, so it doubles as a CI / post-deploy gate.
#
# Read-only and safe to run anytime:
#   sudo bash scripts/server-verify.sh
#
# Honors the same overrides as server-setup.sh (PHP_VERSION, APP_DIR, NODE_MAJOR,
# DB_*, ports). With --verbose / -v it also prints a debug section: versions,
# service status, listening ports, and the tail of relevant logs.
# ----------------------------------------------------------------------------
set -uo pipefail

PHP_VERSION="${PHP_VERSION:-8.4}"
NODE_MAJOR="${NODE_MAJOR:-20}"
APP_DIR="${APP_DIR:-/var/www/html/peta}"
BRIDGE_PORT="${BRIDGE_PORT:-8088}"
APP_USER="${APP_USER:-ubuntu}"        # code owner / deploy user
WEB_USER="${WEB_USER:-www-data}"      # PHP-FPM / Apache runtime user
VERBOSE=false
[[ "${1:-}" == "-v" || "${1:-}" == "--verbose" ]] && VERBOSE=true

C_RESET='\033[0m'; C_GREEN='\033[1;32m'; C_RED='\033[1;31m'; C_YELLOW='\033[1;33m'; C_BLUE='\033[1;34m'
PASS=0; FAIL=0; WARN=0

# check "label" "command..."  → command's exit status decides PASS/FAIL
check() {
    local label="$1"; shift
    if "$@" >/dev/null 2>&1; then
        echo -e "${C_GREEN}  PASS${C_RESET}  ${label}"; ((PASS++))
    else
        echo -e "${C_RED}  FAIL${C_RESET}  ${label}"; ((FAIL++))
    fi
}
# checkout "label" expected substring  cmd...  → PASS if output contains substring
checkout() {
    local label="$1" expect="$2"; shift 2
    local out; out="$("$@" 2>&1)"
    if grep -q -- "$expect" <<<"$out"; then
        echo -e "${C_GREEN}  PASS${C_RESET}  ${label}"; ((PASS++))
    else
        echo -e "${C_RED}  FAIL${C_RESET}  ${label} ${C_YELLOW}(got: $(head -1 <<<"$out"))${C_RESET}"; ((FAIL++))
    fi
}
soft() {  # non-fatal advisory
    local label="$1"; shift
    if "$@" >/dev/null 2>&1; then
        echo -e "${C_GREEN}  PASS${C_RESET}  ${label}"; ((PASS++))
    else
        echo -e "${C_YELLOW}  WARN${C_RESET}  ${label}"; ((WARN++))
    fi
}
section() { echo -e "\n${C_BLUE}── $* ─────────────────────────────${C_RESET}"; }

PHP_BIN="php${PHP_VERSION}"
ART() { "$PHP_BIN" "${APP_DIR}/artisan" "$@"; }

# ── Binaries & versions ─────────────────────────────────────────────────────
section "Toolchain"
check  "php${PHP_VERSION} on PATH"            command -v "$PHP_BIN"
checkout "PHP is ${PHP_VERSION}.x"  "PHP ${PHP_VERSION}"  "$PHP_BIN" -v
check  "Composer on PATH"                     command -v composer
check  "Node on PATH"                         command -v node
if command -v node >/dev/null; then
    NODE_NOW="$(node -v | sed 's/v\([0-9]*\).*/\1/')"
    [[ "$NODE_NOW" -ge "$NODE_MAJOR" ]] \
        && { echo -e "${C_GREEN}  PASS${C_RESET}  Node >= ${NODE_MAJOR} (have $(node -v))"; ((PASS++)); } \
        || { echo -e "${C_RED}  FAIL${C_RESET}  Node >= ${NODE_MAJOR} (have $(node -v))"; ((FAIL++)); }
fi
check  "npm on PATH"                           command -v npm

# ── PHP extensions (required by the app) ────────────────────────────────────
section "PHP extensions"
for ext in pdo_mysql redis mbstring xml curl zip gd bcmath intl openssl; do
    check "ext: ${ext}" bash -c "$PHP_BIN -m | grep -qi '^${ext}\$'"
done

# ── Services ────────────────────────────────────────────────────────────────
section "Services (systemd)"
check  "php${PHP_VERSION}-fpm active"   systemctl is-active --quiet "php${PHP_VERSION}-fpm"
check  "apache2 active"                 systemctl is-active --quiet apache2
check  "mysql active"                   systemctl is-active --quiet mysql
check  "redis-server active"            systemctl is-active --quiet redis-server
check  "horizon.service active"         systemctl is-active --quiet horizon
check  "baileys-wa-bridge active"       systemctl is-active --quiet baileys-wa-bridge
soft   "horizon enabled at boot"        systemctl is-enabled --quiet horizon
soft   "baileys-wa-bridge enabled at boot" systemctl is-enabled --quiet baileys-wa-bridge

# ── Connectivity ────────────────────────────────────────────────────────────
section "Connectivity"
checkout "Redis responds to PING"  "PONG"  redis-cli ping
check    "Apache config is valid"          apachectl configtest
check    "PHP-FPM socket exists"           test -S "/run/php/php${PHP_VERSION}-fpm.sock"
soft     "wa-bridge /health reachable"     bash -c "curl -fsS http://localhost:${BRIDGE_PORT}/health"

# ── Application ─────────────────────────────────────────────────────────────
section "Application (${APP_DIR})"
check  "artisan present"                test -f "${APP_DIR}/artisan"
check  ".env present"                   test -f "${APP_DIR}/.env"
check  "APP_KEY is set"                  bash -c "grep -q '^APP_KEY=base64:' '${APP_DIR}/.env'"
check  "vendor/ installed"              test -d "${APP_DIR}/vendor"
check  "node_modules installed"         test -d "${APP_DIR}/node_modules"
check  "Vite build output exists"       bash -c "ls ${APP_DIR}/public/build/manifest.json ${APP_DIR}/public/build/.vite/manifest.json 2>/dev/null | grep -q ."
check  "storage symlink exists"         test -L "${APP_DIR}/public/storage"
check  "storage writable by web user (${WEB_USER})"  bash -c "sudo -u ${WEB_USER} test -w '${APP_DIR}/storage/logs' 2>/dev/null || test -w '${APP_DIR}/storage/logs'"
check  "wa-bridge node_modules"         test -d "${APP_DIR}/wa-bridge/node_modules"

if [[ -f "${APP_DIR}/artisan" ]]; then
    checkout "DB connection works"      "DB_OK"   bash -c "$PHP_BIN ${APP_DIR}/artisan tinker --execute='DB::connection()->getPdo(); echo \"DB_OK\";' 2>&1"
    checkout "Queue connection is redis" "redis"   bash -c "$PHP_BIN ${APP_DIR}/artisan tinker --execute='echo config(\"queue.default\");' 2>/dev/null"
    soft     "No pending migrations"     bash -c "! $PHP_BIN ${APP_DIR}/artisan migrate:status 2>&1 | grep -q 'Pending'"
fi

# ── HTTP smoke test ─────────────────────────────────────────────────────────
section "HTTP"
soft "Apache serves the app on :80" bash -c "curl -fsS -o /dev/null -w '%{http_code}' http://localhost/ | grep -qE '^(200|302|301)'"

# ── TLS (only meaningful once a domain + certbot cert exist) ─────────────────
section "TLS"
soft "Let's Encrypt cert present"  bash -c "ls /etc/letsencrypt/live/*/fullchain.pem >/dev/null 2>&1"
soft "certbot auto-renewal timer"  systemctl is-enabled --quiet certbot.timer

# ── Verbose debug dump ──────────────────────────────────────────────────────
if $VERBOSE; then
    section "DEBUG: versions"
    "$PHP_BIN" -v | head -1
    composer --version 2>/dev/null
    echo "node $(node -v)  npm $(npm -v)"
    redis-server --version | head -1
    mysql --version

    section "DEBUG: service status"
    for svc in "php${PHP_VERSION}-fpm" apache2 mysql redis-server horizon baileys-wa-bridge; do
        printf '%-26s %s\n' "$svc" "$(systemctl is-active "$svc" 2>/dev/null) / $(systemctl is-enabled "$svc" 2>/dev/null)"
    done

    section "DEBUG: listening ports"
    ss -tlnp 2>/dev/null | grep -E ':(80|443|3306|6379|'"${BRIDGE_PORT}"')\b' || true

    section "DEBUG: PHP modules"
    "$PHP_BIN" -m | tr '\n' ' '; echo

    section "DEBUG: artisan about"
    ART about 2>&1 | head -40 || true

    section "DEBUG: horizon status"
    ART horizon:status 2>&1 || true

    section "DEBUG: recent service logs"
    echo "--- horizon (last 15) ---";            journalctl -u horizon -n 15 --no-pager 2>/dev/null || true
    echo "--- baileys-wa-bridge (last 15) ---";  journalctl -u baileys-wa-bridge -n 15 --no-pager 2>/dev/null || true
    echo "--- laravel log (last 15) ---";        tail -n 15 "${APP_DIR}/storage/logs/laravel.log" 2>/dev/null || true
fi

# ── Summary ─────────────────────────────────────────────────────────────────
section "Summary"
echo -e "  ${C_GREEN}PASS: ${PASS}${C_RESET}   ${C_RED}FAIL: ${FAIL}${C_RESET}   ${C_YELLOW}WARN: ${WARN}${C_RESET}"
if [[ "$FAIL" -gt 0 ]]; then
    echo -e "${C_RED}Environment has problems. Re-run with --verbose for a debug dump.${C_RESET}"
    exit 1
fi
echo -e "${C_GREEN}Environment looks healthy.${C_RESET}"
[[ "$WARN" -gt 0 ]] && echo -e "${C_YELLOW}(Warnings are non-fatal — typically WhatsApp not yet linked, etc.)${C_RESET}"
exit 0
