#!/bin/bash
set -u

DEST="10.1.0.0/16"
STROKE="/usr/libexec/strongswan/stroke"
TUNNEL1="eg334s-team2-vpn1-tunnel1"
TUNNEL2="eg334s-team2-vpn1-tunnel2"
STATE_FILE="/run/eg334s-vti-health.active"
RETRY_SECONDS=60
LAST_RETRY=0
LAST_ROUTE=""

connection_up() { printf '%s\n' "$1" | grep -q "$2.*ESTABLISHED"; }
read_active() { if [ -s "$STATE_FILE" ]; then cat "$STATE_FILE"; else printf unknown; fi; }
write_active() { printf '%s\n' "$1" > "$STATE_FILE"; chmod 600 "$STATE_FILE"; }

set_route() {
  [ "$1" = "$LAST_ROUTE" ] && return
  while ip route del "$DEST" 2>/dev/null; do :; done
  case "$1" in
    primary) ip route add "$DEST" dev vti1 metric 100 ;;
    secondary) ip route add "$DEST" dev vti2 metric 100 ;;
    none) ;;
  esac
  logger -t eg334s-vti-health "active route $1"
  LAST_ROUTE="$1"
}

initiate() { timeout 45 "$STROKE" up "$1" >/dev/null 2>&1 || true; }

while sleep 5; do
  NOW=$(date +%s)
  STATUS=$($STROKE statusall 2>/dev/null || true)
  T1=0; T2=0
  connection_up "$STATUS" "$TUNNEL1" && T1=1
  connection_up "$STATUS" "$TUNNEL2" && T2=1
  ACTIVE=$(read_active)

  # Static VGW return-path selection is not pinned to the Linux route metric.
  # Keep exactly one established SA to prevent asymmetric blackholing.
  if [ "$T1" -eq 1 ] && [ "$T2" -eq 1 ]; then
    if [ "$ACTIVE" = secondary ]; then
      "$STROKE" down "$TUNNEL1" >/dev/null 2>&1 || true; T1=0
    else
      "$STROKE" down "$TUNNEL2" >/dev/null 2>&1 || true; T2=0
      ACTIVE=primary; write_active "$ACTIVE"
    fi
  fi

  if [ "$ACTIVE" = secondary ]; then
    if [ "$T2" -eq 1 ]; then set_route secondary; continue; fi
    set_route none
    if [ $((NOW - LAST_RETRY)) -ge "$RETRY_SECONDS" ]; then
      logger -t eg334s-vti-health "secondary missing; attempting primary recovery"
      initiate "$TUNNEL1"; LAST_RETRY=$NOW
    fi
  else
    if [ "$T1" -eq 1 ]; then write_active primary; set_route primary; continue; fi
    set_route none
    if [ $((NOW - LAST_RETRY)) -ge "$RETRY_SECONDS" ]; then
      logger -t eg334s-vti-health "primary missing; starting standby"
      initiate "$TUNNEL2"; LAST_RETRY=$NOW
    fi
  fi

  STATUS=$($STROKE statusall 2>/dev/null || true)
  if connection_up "$STATUS" "$TUNNEL2"; then
    write_active secondary; set_route secondary
  elif connection_up "$STATUS" "$TUNNEL1"; then
    write_active primary; set_route primary
  fi
done
