#!/usr/bin/env bash
# Enterprise Mail — health-check script.
#
# Checks every required service and prints PASS/FAIL for each. Exits
# non-zero if anything required is unhealthy — errors are never masked or
# swallowed.
#
# Usage: ./scripts/health-check.sh

set -uo pipefail

FAIL=0
BACKEND_URL="${BACKEND_URL:-http://127.0.0.1:3001}"
FRONTEND_URL="${FRONTEND_URL:-http://127.0.0.1:3000}"
PUBLIC_URL="${PUBLIC_URL:-https://mail.nandalinux.com}"
IMAP_HOST="${IMAP_HOST:-127.0.0.1}"
SMTP_HOST="${SMTP_HOST:-127.0.0.1}"

pass() { printf '  \033[1;32mPASS\033[0m  %s\n' "$1"; }
fail() { printf '  \033[1;31mFAIL\033[0m  %s\n' "$1"; FAIL=1; }

check_service() {
  local unit="$1"
  if systemctl is-active --quiet "$unit"; then
    pass "systemctl: $unit is active"
  else
    fail "systemctl: $unit is NOT active"
  fi
}

echo "== systemd services =="
check_service postgresql
check_service postfix
check_service dovecot
check_service apache2
check_service enterprise-mail-backend
check_service enterprise-mail-frontend

echo
echo "== failed units (should be empty) =="
failed_units="$(systemctl --failed --no-legend 2>/dev/null)"
if [[ -z "$failed_units" ]]; then
  pass "no failed systemd units"
else
  fail "failed units present:"
  echo "$failed_units"
fi

echo
echo "== PostgreSQL =="
if command -v pg_isready >/dev/null 2>&1 && pg_isready -q; then
  pass "pg_isready"
else
  fail "pg_isready did not report ready"
fi

echo
echo "== Postfix =="
if command -v postfix >/dev/null 2>&1 && postfix check 2>/dev/null; then
  pass "postfix check"
else
  fail "postfix check failed"
fi
if (echo > /dev/tcp/"$SMTP_HOST"/25) 2>/dev/null; then
  pass "SMTP port 25 accepting connections"
else
  fail "SMTP port 25 not reachable on $SMTP_HOST"
fi
if (echo > /dev/tcp/"$SMTP_HOST"/587) 2>/dev/null; then
  pass "SMTP submission port 587 accepting connections"
else
  fail "SMTP submission port 587 not reachable on $SMTP_HOST"
fi

echo
echo "== Dovecot =="
if command -v doveconf >/dev/null 2>&1 && doveconf -n >/dev/null 2>&1; then
  pass "doveconf -n parses cleanly"
else
  fail "doveconf -n failed to parse configuration"
fi
if (echo > /dev/tcp/"$IMAP_HOST"/993) 2>/dev/null; then
  pass "IMAPS port 993 accepting connections"
else
  fail "IMAPS port 993 not reachable on $IMAP_HOST"
fi

echo
echo "== Apache2 =="
if command -v apache2ctl >/dev/null 2>&1 && apache2ctl configtest 2>&1 | grep -q "Syntax OK"; then
  pass "apache2ctl configtest: Syntax OK"
else
  fail "apache2ctl configtest failed"
fi

echo
echo "== Application =="
if curl -fsS "$BACKEND_URL/api/health" >/dev/null 2>&1; then
  pass "backend liveness: $BACKEND_URL/api/health"
else
  fail "backend liveness check failed: $BACKEND_URL/api/health"
fi
if curl -fsS "$BACKEND_URL/api/ready" >/dev/null 2>&1; then
  pass "backend readiness: $BACKEND_URL/api/ready"
else
  fail "backend readiness check failed (may be degraded — see response body): $BACKEND_URL/api/ready"
fi
if curl -fsS "$FRONTEND_URL/" >/dev/null 2>&1; then
  pass "frontend SSR server responds: $FRONTEND_URL/"
else
  fail "frontend SSR server did not respond: $FRONTEND_URL/"
fi
if curl -fsSk "$PUBLIC_URL/" >/dev/null 2>&1; then
  pass "public HTTPS endpoint responds: $PUBLIC_URL/"
else
  fail "public HTTPS endpoint did not respond: $PUBLIC_URL/ (DNS/TLS not live yet? see docs/dns.md)"
fi

echo
echo "== Listening ports (ss -lntup) =="
ss -lntup 2>/dev/null | grep -E ':(25|587|465|993|143|80|443|3000|3001|5432)\b' || echo "  (ss not available or nothing matched)"

echo
if [[ "$FAIL" == "0" ]]; then
  echo "All checks passed."
else
  echo "One or more checks FAILED. See above."
fi
exit $FAIL
