#!/usr/bin/env bash
set -euo pipefail

WARN_DAYS=14
CRIT_DAYS=7

### --- detect mode ---------------------------------------------------------
if [[ "${1:-}" == "--detect" ]]; then
  command -v apache2ctl >/dev/null 2>&1 || exit 1

  if systemctl list-unit-files apache2.service >/dev/null 2>&1; then
    systemctl is-enabled apache2.service >/dev/null 2>&1 || exit 1
    exit 0
  fi

  exit 1
fi

now=$(date +%s)

# 1) vhost-defining files
vhost_files=$(
  apache2ctl -t -D DUMP_VHOSTS 2>/dev/null \
    | sed -n 's/.*(\(\/[^:]*\):[0-9]\+).*/\1/p'
)

# 2) included files (loaded by Apache)
include_files=$(
  apache2ctl -t -D DUMP_INCLUDES 2>/dev/null \
    | awk '{for (i=1;i<=NF;i++) if ($i ~ /^\//) print $i}'
)

# Union of both
mapfile -t cfg_files < <( { echo "$vhost_files"; echo "$include_files"; } | sort -u )

# Extract SSLCertificateFile from loaded files
certs=$(
  for f in "${cfg_files[@]}"; do
    [[ -r "$f" ]] || continue
    awk '
      { sub(/#.*/, "", $0) }                    # strip comments
      $1 == "SSLCertificateFile" { print $2 }   # directive path
    ' "$f"
  done | sort -u
)

echo "<<<local>>>"

while read -r cert; do
  [[ -n "${cert:-}" ]] || continue

  # Resolve relative paths if they ever appear
  if [[ "$cert" != /* ]]; then
    server_root=$(apache2ctl -V 2>/dev/null | awk -F'"' '/HTTPD_ROOT/ {print $2; exit}')
    [[ -n "${server_root:-}" ]] && cert="${server_root%/}/$cert"
  fi

  [[ -f "$cert" ]] || continue

  end=$(openssl x509 -enddate -noout -in "$cert" 2>/dev/null | cut -d= -f2)
  [[ -n "$end" ]] || continue

  end_ts=$(date -d "$end" +%s)
  days=$(( (end_ts - now) / 86400 ))

  cn=$(openssl x509 -noout -subject -nameopt RFC2253 -in "$cert" 2>/dev/null | sed -n 's/.*CN=\([^,]*\).*/\1/p')

  if (( days < CRIT_DAYS )); then
    state=2; txt="CRIT"
  elif (( days < WARN_DAYS )); then
    state=1; txt="WARN"
  else
    state=0; txt="OK"
  fi

  echo "$state \"Cert $cn ($cert)\" days_left=${days};${WARN_DAYS};${CRIT_DAYS};0 $txt - CN=$cn, expires in $days days"
done <<< "$certs"
