#!/bin/bash
set -uo pipefail

DEFAULT_OK_CODES=(200 301 302 401)
OK_CODES=()
SITES=()
NO_SITES=false
CADDYFILE="/opt/git/caddy/Caddyfile"
EXITCODE=0

usage() {
  cat <<EOF
Usage: $0 [--ok-codes CODES] [--sites SITE_LIST] [--no-sites] [--help]

Options:
  --ok-codes CODES   Comma-separated list of HTTP codes considered OK (e.g., "200,301,401").
                     Default: 200,301,302,401
  --sites SITES      Comma-separated list of sites to test (e.g., "site1.com,site2.com").
                     If not provided, all sites from the Caddyfile will be tested.
  --no-sites         Skip all tests and exit immediately (overrides --sites and Caddyfile).
  --help             Show this help message and exit.

Examples:
  $0                                 # test all sites from Caddyfile
  $0 --sites example.com             # test only example.com
  $0 --no-sites                      # do not test anything, exit immediately
  $0 --ok-codes 200,401 --sites test.com
EOF
}

# Argument parsing
while [[ $# -gt 0 ]]; do
  case $1 in
    --ok-codes)
      IFS=',' read -r -a OK_CODES <<< "$2"
      shift 2
      ;;
    --sites)
      IFS=',' read -r -a SITES <<< "$2"
      shift 2
      ;;
    --no-sites)
      NO_SITES=true
      shift
      ;;
    --help)
      usage
      exit 0
      ;;
    --*)
      echo "Unknown argument: $1" >&2
      usage
      exit 1
      ;;
    *)
      echo "Unexpected argument: $1" >&2
      usage
      exit 1
      ;;
  esac
done

# Handle early exit if --no-sites is set
if $NO_SITES; then
  echo "🚫 No sites to test (per --no-sites). Exiting."
  exit 0
fi

# Use default OK codes if not provided
if [[ ${#OK_CODES[@]} -eq 0 ]]; then
  OK_CODES=("${DEFAULT_OK_CODES[@]}")
fi

# Ensure curl and gawk are installed (Debian only)
if ! command -v curl >/dev/null 2>&1; then
  sudo apt-get update && sudo apt-get install -y curl
fi

if ! command -v gawk >/dev/null 2>&1; then
  sudo apt-get update && sudo apt-get install -y gawk
fi

# If no --sites provided, extract from Caddyfile
if [[ ${#SITES[@]} -eq 0 ]]; then
  mapfile -t SITES < <(
    gawk '/^[^# \t(].*{$/ {for (i=1; i<=NF; i++) {if ($i ~ /{$/) break; print $i}}' "$CADDYFILE"
  )
fi

# Test each site
for site in "${SITES[@]}"; do
  echo "🌐 Testing https://$site/"
  http_code=$(curl -ksSL -o /dev/null -w "%{http_code}" "https://$site/")
  is_ok=false
  for code in "${OK_CODES[@]}"; do
    if [[ "$http_code" == "$code" ]]; then
      is_ok=true
      break
    fi
  done
  if $is_ok; then
    echo "✅ $site OK (HTTP $http_code)"
  else
    echo "❌ $site FAILED (HTTP $http_code)"
    EXITCODE=1
  fi
done

exit $EXITCODE