#!/bin/sh
set -eu
umask 077

COMMAND="${1:-${SSH_ORIGINAL_COMMAND:-status}}"
CONF="/path/to/vpn-platform/gateway/config/vpn-clients.conf"
APPLY="/path/to/vpn-platform/gateway/apply-gateway-rules.sh"
TMP="$(mktemp /tmp/olivetin-vpn-clients.XXXXXX)"
trap 'rm -f "$TMP"' EXIT

status() {
  echo "HOST=$(hostname)"
  echo "CONFIG=$CONF"
  echo "CLIENTS=$(grep -c '|' "$CONF" 2>/dev/null || true)"
  sha256sum "$CONF"
}

case "$COMMAND" in
  status)
    status
    exit 0
    ;;

  apply)
    cat > "$TMP"

    SIZE="$(wc -c < "$TMP")"
    [ "$SIZE" -gt 0 ] && [ "$SIZE" -le 32768 ] || {
      echo "[STOPP] Uebergabedatei ist leer oder zu gross."
      exit 65
    }

    awk -F'|' '
    function stop(t){print "[STOPP] Zeile " NR ": " t; bad=1}
    NF!=3 {stop("genau drei Felder erforderlich"); next}
    $1 !~ /^[A-Za-z0-9][A-Za-z0-9._-]{0,39}$/ {stop("ungueltiger Geraetename")}
    $2 !~ /^192\.168\.100\.[0-9]+\/32$/ {stop("ungueltige Client-IP (erwartet 192.168.100.x/32)"); next}
    {
      ip=$2
      sub(/^192\.168\.100\./,"",ip)
      sub(/\/32$/,"",ip)
      n=ip+0; if(n<2 || n>254) stop("IP ausserhalb des Clientnetzes")
      if(n==5 || n==10 || n==20 || n==112 || n==250)
        stop("reservierte oder ausgeschlossene IP (NAS, VIP, etc.)")
      if(seen[$2]++) stop("doppelte Client-IP")
      if($3=="") stop("Beschreibung fehlt")
    }
    END {
      if(NR<1) stop("keine Clients")
      if(NR>64) stop("zu viele Clients")
      exit bad ? 1 : 0
    }' "$TMP" || exit 65

    while IFS='|' read -r OLD_NAME OLD_IP OLD_DESC; do
      [ -n "$OLD_IP" ] || continue
      grep -q "^${OLD_NAME}|" "$TMP" || {
        echo "[STOPP] Bestehende geraete_id $OLD_NAME fehlt; Loeschungen sind hier nicht erlaubt."
        exit 65
      }
    done < "$CONF"

    BACKUP="${CONF}.bak-olivetin-sync-$(date +%Y%m%d-%H%M%S)"
    cp -p "$CONF" "$BACKUP"
    cat "$TMP" > "$CONF"

    if ! "$APPLY"; then
      cat "$BACKUP" > "$CONF"
      "$APPLY" >/dev/null 2>&1 || true
      echo "[STOPP] Gateway-Regeln konnten nicht angewendet werden."
      exit 66
    fi

    while IFS='|' read -r NAME CIDR DESC; do
      IP="${CIDR%/32}"
      ip rule show | grep -Fq "from $IP lookup 201" || {
        cat "$BACKUP" > "$CONF"
        "$APPLY" >/dev/null 2>&1 || true
        echo "[STOPP] Regel fuer $IP wurde nicht nachgewiesen."
        exit 67
      }
    done < "$CONF"

    echo "[OK] VPN-Clientliste angewendet und Tabelle 201 geprueft."
    status
    ;;

  *)
    echo "[ABGELEHNT] Nur status oder apply sind freigegeben."
    exit 64
    ;;
esac