#!/bin/sh
set -eu

# Atomic Nginx upstream switch with validation and automatic config rollback.
# This script performs no action unless invoked with preflight, go, legacy, or status.

action=${1:-status}
active_include=${NGINX_ACTIVE_INCLUDE:-}
go_upstream=${GO_UPSTREAM:-gateway-api:8080}
legacy_upstream=${LEGACY_UPSTREAM:-legacy-gateway:8000}
go_health=${GO_HEALTH_URL:-http://127.0.0.1:8080/readyz}
legacy_health=${LEGACY_HEALTH_URL:-http://127.0.0.1:8000/readyz}
public_health=${PUBLIC_HEALTH_URL:-}
nginx_bin=${NGINX_BIN:-nginx}

probe() {
  curl -fsS --max-time 5 "$1" >/dev/null
}

preflight() {
  probe "$go_health"
  probe "$legacy_health"
  "$nginx_bin" -t
  echo "preflight ok: Go and legacy are ready; Nginx configuration is valid"
}

status() {
  if [ -z "$active_include" ] || [ ! -f "$active_include" ]; then
    echo "active upstream include is not configured or does not exist"
    exit 1
  fi
  sed -n '1,3p' "$active_include"
}

switch_to() {
  target_name=$1
  target_address=$2
  target_health=$3
  if [ -z "$active_include" ]; then
    echo "NGINX_ACTIVE_INCLUDE is required" >&2
    exit 2
  fi
  probe "$target_health"
  directory=$(dirname "$active_include")
  timestamp=$(date -u +%Y%m%dT%H%M%SZ)
  backup="${active_include}.backup.${timestamp}"
  temporary="${directory}/.ai-gateway-upstream.${timestamp}.tmp"
  if [ -f "$active_include" ]; then
    cp -p "$active_include" "$backup"
  fi
  umask 027
  {
    echo "# ai-gateway-active=${target_name} switched_at=${timestamp}"
    echo "upstream ai_gateway_active {"
    echo "    server ${target_address};"
    echo "    keepalive 128;"
    echo "}"
  } >"$temporary"
  mv "$temporary" "$active_include"
  if ! "$nginx_bin" -t; then
    if [ -f "$backup" ]; then mv "$backup" "$active_include"; fi
    echo "Nginx validation failed; previous include restored" >&2
    exit 1
  fi
  if ! "$nginx_bin" -s reload; then
    if [ -f "$backup" ]; then mv "$backup" "$active_include"; "$nginx_bin" -s reload || true; fi
    echo "Nginx reload failed; previous include restored" >&2
    exit 1
  fi
  if [ -n "$public_health" ] && ! probe "$public_health"; then
    if [ -f "$backup" ]; then mv "$backup" "$active_include"; "$nginx_bin" -t; "$nginx_bin" -s reload; fi
    echo "public health probe failed; traffic rolled back" >&2
    exit 1
  fi
  echo "active upstream switched to ${target_name}; backup: ${backup}"
}

case "$action" in
  preflight) preflight ;;
  status) status ;;
  go) switch_to go "$go_upstream" "$go_health" ;;
  legacy|rollback) switch_to legacy "$legacy_upstream" "$legacy_health" ;;
  *) echo "usage: $0 {preflight|status|go|legacy|rollback}" >&2; exit 2 ;;
esac
