#!/bin/bash
# ============================================================
#  REBOOTLY — Ajout automatique d'un nouveau nœud Proxmox
#  Architecture : hub-and-spoke WireGuard
#
#  À lancer sur le serveur VPN (51.178.43.243) en tant que root.
#
#  Ce que ça fait :
#    - Détecte automatiquement le prochain slot disponible
#    - Assigne tunnel_ip (10.8.0.N) et LXC subnet (10.10.N.0/24)
#    - SSH vers le Proxmox : install WireGuard + clés + config
#    - Ajoute le peer dans wg1 (hub Proxmox) sur le VPN
#    - Recharge wg1 à chaud (clients wg0 non perturbés)
#    - Test de connectivité bidirectionnel
#    - Affiche les infos à enregistrer dans le portail admin
#
#  Architecture réseau :
#    wg0 VPN (10.38.96.0/21) ← clients Rebootly Connect (2046 max)
#    wg1 VPN (10.8.0.1/24)   ← hub Proxmox (ce script gère wg1)
#      ├── Proxmox 1 → tunnel 10.8.0.2, LXC 10.10.1.0/24
#      ├── Proxmox 2 → tunnel 10.8.0.3, LXC 10.10.2.0/24
#      └── Proxmox N → tunnel 10.8.0.(N+1), LXC 10.10.N.0/24
#
#  Usage :
#    bash 09-add-new-proxmox.sh [<IP_PROXMOX>] [<MOT_DE_PASSE>]
# ============================================================

set -euo pipefail

GREEN='\033[0;32m'; CYAN='\033[0;36m'; YELLOW='\033[1;33m'
RED='\033[0;31m'; BOLD='\033[1m'; NC='\033[0m'
ok()      { echo -e "${GREEN}[✓]${NC} $1"; }
section() { echo -e "\n${CYAN}${BOLD}┌─ $1 ──${NC}"; }
warn()    { echo -e "${YELLOW}[!]${NC} $1"; }
err()     { echo -e "${RED}[✗]${NC} $1"; exit 1; }
info()    { echo -e "    ${CYAN}→${NC} $1"; }

[[ $EUID -ne 0 ]] && err "Root requis (lancer sur le serveur VPN)"

# ─── Config statique VPN ─────────────────────────────────────
VPN_PUBLIC_IP="51.178.43.243"
WG_DIR="/etc/wireguard"

# wg0 — clients Rebootly Connect (inchangé par ce script)
WG0_IFACE="wg0"
WG0_NET="10.38.96.0/21"         # 2046 clients max

# wg1 — hub Proxmox
WG1_IFACE="wg1"
WG1_CONF="$WG_DIR/${WG1_IFACE}.conf"
WG1_PORT="51821"
WG1_VPN_IP="10.8.0.1"       # IP du VPN dans le hub (fixe)
WG1_HUB_NET="10.8.0.0/24"   # Réseau du hub

SSH_PORT="22"

# ─── Arguments CLI ───────────────────────────────────────────
PROXMOX_IP="${1:-}"
SSH_PASS="${2:-}"

# ─── Bannière ────────────────────────────────────────────────
clear
echo -e "${CYAN}${BOLD}"
echo "  ┌─────────────────────────────────────────────────────┐"
echo "  │  Rebootly — Ajout Proxmox (hub-and-spoke wg1)      │"
echo "  │  VPN : ${VPN_PUBLIC_IP}                             │"
echo "  └─────────────────────────────────────────────────────┘"
echo -e "${NC}"

# ─── Vérifications préalables ────────────────────────────────
[[ ! -f "$WG_DIR/wg0.conf" ]] && err "wg0.conf introuvable — lancer 00-setup-vpn-complete.sh d'abord"

# Initialiser wg1 si absent
if [[ ! -f "$WG1_CONF" ]]; then
  info "wg1 non configuré — initialisation du hub Proxmox..."
  if [[ ! -f "$WG_DIR/wg1_private.key" ]]; then
    wg genkey | tee "$WG_DIR/wg1_private.key" | wg pubkey > "$WG_DIR/wg1_public.key"
    chmod 600 "$WG_DIR/wg1_private.key"
  fi
  WG1_PRIVATE=$(cat "$WG_DIR/wg1_private.key")
  cat > "$WG1_CONF" << EOF
# ============================================================
#  Rebootly VPN — wg1 : Hub Proxmox (hub-and-spoke)
#  Généré le $(date '+%Y-%m-%d %H:%M')
#  Hub : ${WG1_VPN_IP}/24
# ============================================================

[Interface]
Address    = ${WG1_VPN_IP}/24
ListenPort = ${WG1_PORT}
PrivateKey = ${WG1_PRIVATE}

# Routes LXC ajoutées automatiquement par 09-add-new-proxmox.sh

# ── Peers Proxmox (ajoutés automatiquement) ─────────────────
EOF
  chmod 600 "$WG1_CONF"
  systemctl enable wg-quick@wg1 2>/dev/null || true
  systemctl start wg-quick@wg1 || true
  ok "wg1 hub initialisé (${WG1_VPN_IP}/24, port ${WG1_PORT})"
fi

# ─── Détecter le prochain slot disponible ────────────────────
# Les IPs 10.8.0.2, 10.8.0.3, ... sont assignées aux Proxmox
# Le dernier octet utilisé = index du Proxmox + 1
USED_TUNNEL_OCTETS=$(grep -oP '10\.8\.0\.\K[0-9]+' "$WG1_CONF" 2>/dev/null | grep -v "^1$" | sort -n || true)
NEXT_OCTET=2
for octet in $(seq 2 254); do
  if ! echo "$USED_TUNNEL_OCTETS" | grep -qw "$octet" 2>/dev/null; then
    NEXT_OCTET=$octet
    break
  fi
done

# Index du nœud (Proxmox 1 = octet 2, index 1 / Proxmox 2 = octet 3, index 2...)
NODE_INDEX=$(( NEXT_OCTET - 1 ))
SUGGESTED_TUNNEL_IP="10.8.0.${NEXT_OCTET}"
SUGGESTED_LXC_SUBNET="10.10.${NODE_INDEX}.0/24"
SUGGESTED_POOL_START="10.10.${NODE_INDEX}.10"
SUGGESTED_POOL_END="10.10.${NODE_INDEX}.254"
SUGGESTED_GATEWAY="10.10.${NODE_INDEX}.1"
SUGGESTED_LXC_ID_START=$(( 60000 + (NODE_INDEX - 1) * 10000 ))
SUGGESTED_LXC_ID_END=$(( 60000 + NODE_INDEX * 10000 - 1 ))

# ─── Collecte des informations ───────────────────────────────
section "Paramètres nœud Proxmox"

if [[ -z "$PROXMOX_IP" ]]; then
  read -p "  IP publique du nouveau Proxmox                  : " PROXMOX_IP
fi
[[ -z "$PROXMOX_IP" ]] && err "IP Proxmox obligatoire"

read -p "  Nom du nœud (ex: proxmox-fr-2) [proxmox-${NODE_INDEX}] : " PROXMOX_NAME
PROXMOX_NAME="${PROXMOX_NAME:-proxmox-${NODE_INDEX}}"

read -p "  Port SSH [22]                                   : " INPUT
SSH_PORT="${INPUT:-22}"

if [[ -z "$SSH_PASS" ]]; then
  read -s -p "  Mot de passe SSH root@${PROXMOX_IP}             : " SSH_PASS; echo
fi
[[ -z "$SSH_PASS" ]] && err "Mot de passe SSH obligatoire"

echo ""
echo -e "  ${YELLOW}Assignation automatique (hub-and-spoke) :${NC}"
echo -e "  Tunnel IP Proxmox  : ${BOLD}$SUGGESTED_TUNNEL_IP${NC}"
echo -e "  Subnet LXC         : ${BOLD}$SUGGESTED_LXC_SUBNET${NC}"
echo -e "  Pool IPs LXC       : ${BOLD}$SUGGESTED_POOL_START → $SUGGESTED_POOL_END${NC}"
echo -e "  LXC IDs            : ${BOLD}$SUGGESTED_LXC_ID_START → $SUGGESTED_LXC_ID_END${NC}"
echo ""
read -p "  Accepter ces valeurs ? [O/n] " -n 1 -r; echo
if [[ "$REPLY" =~ ^[nN]$ ]]; then
  read -p "  Tunnel IP Proxmox (dans 10.8.0.x) : " TUNNEL_IP
  read -p "  Subnet LXC (ex: 10.10.2.0/24)    : " LXC_SUBNET
  read -p "  Gateway LXC (ex: 10.10.2.1)       : " LXC_GATEWAY
else
  TUNNEL_IP="$SUGGESTED_TUNNEL_IP"
  LXC_SUBNET="$SUGGESTED_LXC_SUBNET"
  LXC_GATEWAY="$SUGGESTED_GATEWAY"
fi

echo ""
echo -e "  ${YELLOW}Résumé final :${NC}"
echo -e "  Proxmox public  : ${BOLD}$PROXMOX_IP:$SSH_PORT${NC}"
echo -e "  Nom nœud        : ${BOLD}$PROXMOX_NAME${NC}"
echo -e "  Tunnel IP       : ${BOLD}$TUNNEL_IP${NC} (dans hub wg1 $WG1_VPN_IP)"
echo -e "  LXC subnet      : ${BOLD}$LXC_SUBNET${NC} (gateway $LXC_GATEWAY)"
echo ""
read -p "  Continuer ? [o/N] " -n 1 -r; echo
[[ ! $REPLY =~ ^[oO]$ ]] && echo "Annulé." && exit 0

# ─── Helper SSH ──────────────────────────────────────────────
SSH_OPTS="-o StrictHostKeyChecking=no -o ConnectTimeout=15 -p $SSH_PORT"

ssh_cmd() {
  sshpass -p "$SSH_PASS" ssh $SSH_OPTS root@${PROXMOX_IP} "$@"
}

# ─── Prérequis : sshpass ─────────────────────────────────────
if ! command -v sshpass >/dev/null 2>&1; then
  apt-get install -y sshpass >/dev/null 2>&1
fi

# ─── 1. Test SSH ─────────────────────────────────────────────
section "1/6 — Test connexion SSH"
ssh_cmd 'echo SSH_OK' 2>/dev/null | grep -q SSH_OK \
  || err "Connexion SSH impossible vers $PROXMOX_IP:$SSH_PORT"
ok "SSH root@${PROXMOX_IP}:${SSH_PORT} OK"

# ─── 2. Installation WireGuard sur Proxmox ───────────────────
section "2/6 — Installation WireGuard sur Proxmox"
ssh_cmd 'bash -s' << 'REMOTE_INSTALL'
set -e
apt-get update -qq
apt-get install -y wireguard wireguard-tools >/dev/null 2>&1
sysctl -w net.ipv4.ip_forward=1 >/dev/null
grep -q "net.ipv4.ip_forward=1" /etc/sysctl.conf || echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
mkdir -p /etc/wireguard && chmod 700 /etc/wireguard
echo "INSTALL_OK"
REMOTE_INSTALL
ok "WireGuard installé sur Proxmox"

# ─── 3. Génération des clés sur Proxmox ──────────────────────
section "3/6 — Génération des clés WireGuard Proxmox"
PROXMOX_PUBLIC=$(ssh_cmd 'bash -s' << 'REMOTE_KEYGEN'
set -e
WG_DIR="/etc/wireguard"
if [[ ! -f "$WG_DIR/proxmox_private.key" ]]; then
  wg genkey | tee "$WG_DIR/proxmox_private.key" | wg pubkey > "$WG_DIR/proxmox_public.key"
  chmod 600 "$WG_DIR/proxmox_private.key"
fi
cat "$WG_DIR/proxmox_public.key"
REMOTE_KEYGEN
)
PROXMOX_PUBLIC=$(echo "$PROXMOX_PUBLIC" | tr -d '[:space:]')
[[ -z "$PROXMOX_PUBLIC" ]] && err "Échec récupération clé publique Proxmox"
ok "Clé publique Proxmox : ${PROXMOX_PUBLIC:0:24}..."

# ─── 4. Config wg-proxmox.conf sur le Proxmox ────────────────
section "4/6 — Configuration tunnel wg-proxmox sur Proxmox"

# Récupérer la clé publique de wg1 sur le VPN
WG1_PUBKEY=$(cat "$WG_DIR/wg1_public.key")

sshpass -p "$SSH_PASS" ssh $SSH_OPTS root@${PROXMOX_IP} \
  "TUNNEL_IP='$TUNNEL_IP' LXC_SUBNET='$LXC_SUBNET' WG0_NET='$WG0_NET' \
   VPN_PUBLIC_IP='$VPN_PUBLIC_IP' WG1_PORT='$WG1_PORT' WG1_PUBKEY='$WG1_PUBKEY' \
   LXC_GATEWAY='$LXC_GATEWAY' bash -s" << 'REMOTE_CONF'
set -e
WG_DIR="/etc/wireguard"
PRIVATE_KEY=$(cat "$WG_DIR/proxmox_private.key")
IFACE="wg-vpn"

# Backup si existant
[[ -f "$WG_DIR/${IFACE}.conf" ]] && \
  cp "$WG_DIR/${IFACE}.conf" "$WG_DIR/${IFACE}.conf.backup.$(date +%Y%m%d-%H%M%S)"

# Interface LXC (vmbr1 si présent, sinon vmbr0)
LXC_BRIDGE="vmbr1"
if ! ip link show vmbr1 &>/dev/null; then
  LXC_BRIDGE="vmbr0"
fi

cat > "$WG_DIR/${IFACE}.conf" << WGEOF
# ============================================================
#  Rebootly — Tunnel Proxmox → Hub VPN (wg1)
#  Généré le $(date '+%Y-%m-%d %H:%M')
#  Tunnel IP : ${TUNNEL_IP}
#  LXC subnet: ${LXC_SUBNET}
# ============================================================

[Interface]
Address    = ${TUNNEL_IP}/32
PrivateKey = ${PRIVATE_KEY}

# Forward : clients WG peuvent accéder aux LXC via ce Proxmox
PostUp   = iptables -A FORWARD -i ${IFACE} -o ${LXC_BRIDGE} -j ACCEPT
PostUp   = iptables -A FORWARD -i ${LXC_BRIDGE} -o ${IFACE} -j ACCEPT
PostUp   = iptables -t nat -A POSTROUTING -s ${WG0_NET} -o ${LXC_BRIDGE} -j MASQUERADE
PostDown = iptables -D FORWARD -i ${IFACE} -o ${LXC_BRIDGE} -j ACCEPT 2>/dev/null || true
PostDown = iptables -D FORWARD -i ${LXC_BRIDGE} -o ${IFACE} -j ACCEPT 2>/dev/null || true
PostDown = iptables -t nat -D POSTROUTING -s ${WG0_NET} -o ${LXC_BRIDGE} -j MASQUERADE 2>/dev/null || true

[Peer]
# Hub VPN wg1 — ${VPN_PUBLIC_IP}
PublicKey           = ${WG1_PUBKEY}
Endpoint            = ${VPN_PUBLIC_IP}:${WG1_PORT}
# Permettre aux clients WireGuard (10.38.96.0/21) d'atteindre ce Proxmox
AllowedIPs          = ${WG0_NET}
PersistentKeepalive = 25
WGEOF

chmod 600 "$WG_DIR/${IFACE}.conf"

# Démarrer l'interface
systemctl enable wg-quick@wg-vpn 2>/dev/null || true
systemctl stop wg-quick@wg-vpn 2>/dev/null || true
systemctl start wg-quick@wg-vpn
echo "WG_STARTED"
REMOTE_CONF

ok "Interface wg-vpn configurée et démarrée sur Proxmox"

# ─── 5. Ajout du peer Proxmox dans wg1 VPN ───────────────────
section "5/6 — Enregistrement du peer Proxmox dans wg1 (hub VPN)"

# Backup wg1.conf
cp "$WG1_CONF" "${WG1_CONF}.backup.$(date +%Y%m%d-%H%M%S)"

if grep -q "$PROXMOX_PUBLIC" "$WG1_CONF" 2>/dev/null; then
  warn "Peer déjà présent dans wg1.conf — skip"
else
  cat >> "$WG1_CONF" << EOF

# ── ${PROXMOX_NAME} — ${PROXMOX_IP} — ajouté le $(date '+%Y-%m-%d %H:%M') ──
[Peer]
PublicKey  = ${PROXMOX_PUBLIC}
# Tunnel IP du Proxmox + son subnet LXC complet
AllowedIPs = ${TUNNEL_IP}/32, ${LXC_SUBNET}
EOF
  ok "Peer $PROXMOX_NAME ajouté dans wg1.conf"
fi

# Recharger wg1 à chaud
if systemctl is-active wg-quick@wg1 &>/dev/null; then
  wg syncconf "$WG1_IFACE" <(wg-quick strip "$WG1_IFACE")
  ok "wg1 rechargé à chaud"
else
  systemctl start wg-quick@wg1
  ok "wg1 démarré"
fi

# Ajouter route LXC subnet → Proxmox dans le kernel (immédiat)
ip route replace "$LXC_SUBNET" via "$TUNNEL_IP" dev "$WG1_IFACE" 2>/dev/null || true
ok "Route $LXC_SUBNET → $TUNNEL_IP (dev $WG1_IFACE) ajoutée"

# ─── 6. Test de connectivité ─────────────────────────────────
section "6/6 — Test de connectivité"
info "Attente établissement tunnel (5s)..."
sleep 5

if ping -c 3 -W 3 "$TUNNEL_IP" >/dev/null 2>&1; then
  ok "Ping VPN → Proxmox tunnel ($TUNNEL_IP) ✓"
else
  warn "Ping VPN → Proxmox ($TUNNEL_IP) échoué — vérifier firewall/iptables"
fi

# État wg1 après ajout
echo ""
echo -e "  ${CYAN}Peers actifs sur wg1 :${NC}"
wg show "$WG1_IFACE" peers 2>/dev/null | while read -r pubkey; do
  latest=$(wg show "$WG1_IFACE" latest-handshakes 2>/dev/null | grep "^$pubkey" | awk '{print $2}')
  allowed=$(wg show "$WG1_IFACE" allowed-ips 2>/dev/null | grep "^$pubkey" | awk '{$1=""; print $0}' | xargs)
  if [[ -n "$latest" && "$latest" != "0" ]]; then
    ago=$(( $(date +%s) - latest ))
    echo -e "  ${GREEN}●${NC} ${pubkey:0:20}... → handshake il y a ${ago}s — $allowed"
  else
    echo -e "  ${YELLOW}○${NC} ${pubkey:0:20}... → pas encore connecté — $allowed"
  fi
done

# ─── Sauvegarder infos nœud ──────────────────────────────────
mkdir -p /root/proxmox-nodes
INFO_FILE="/root/proxmox-nodes/${PROXMOX_NAME}.conf"
cat > "$INFO_FILE" << EOF
# Rebootly — Nœud Proxmox ${PROXMOX_NAME}
# Ajouté le $(date '+%Y-%m-%d %H:%M')
PROXMOX_NAME=${PROXMOX_NAME}
PROXMOX_IP=${PROXMOX_IP}
PROXMOX_SSH_PORT=${SSH_PORT}
TUNNEL_IP=${TUNNEL_IP}
LXC_SUBNET=${LXC_SUBNET}
LXC_GATEWAY=${LXC_GATEWAY}
POOL_START=${SUGGESTED_POOL_START}
POOL_END=${SUGGESTED_POOL_END}
LXC_ID_START=${SUGGESTED_LXC_ID_START}
LXC_ID_END=${SUGGESTED_LXC_ID_END}
PROXMOX_WG_PUBKEY=${PROXMOX_PUBLIC}
ADDED=$(date '+%Y-%m-%d %H:%M')
EOF
chmod 600 "$INFO_FILE"
ok "Infos sauvegardées → $INFO_FILE"

# ─── Résumé + instructions portail ───────────────────────────
echo ""
echo -e "${CYAN}${BOLD}╔══════════════════════════════════════════════════════════╗"
echo -e "║  Nœud Proxmox intégré au hub VPN wg1               ✓  ║"
echo -e "╠══════════════════════════════════════════════════════════╣"
printf  "║  Nom          : %-39s║\n" "$PROXMOX_NAME"
printf  "║  IP publique  : %-39s║\n" "$PROXMOX_IP"
printf  "║  Tunnel IP    : %-39s║\n" "$TUNNEL_IP"
printf  "║  LXC subnet   : %-39s║\n" "$LXC_SUBNET"
printf  "║  Pool IPs     : %-39s║\n" "${SUGGESTED_POOL_START} → ${SUGGESTED_POOL_END}"
printf  "║  LXC IDs      : %-39s║\n" "${SUGGESTED_LXC_ID_START} → ${SUGGESTED_LXC_ID_END}"
echo -e "╠══════════════════════════════════════════════════════════╣"
echo -e "║  À FAIRE — Enregistrer dans le portail admin :          ║"
echo -e "║  /admin/nodes/add avec les valeurs ci-dessus            ║"
echo -e "╠══════════════════════════════════════════════════════════╣"
echo -e "║  Clé publique WireGuard Proxmox :                       ║"
echo -e "║  (à coller dans portail → Clé WG du nœud)              ║"
echo -e "╚══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "  ${BOLD}Clé publique WireGuard :${NC}"
echo -e "  ${GREEN}$PROXMOX_PUBLIC${NC}"
echo ""
echo -e "  ${YELLOW}Étapes suivantes :${NC}"
echo -e "  1. Portail admin → /admin/nodes/add → saisir les valeurs ci-dessus"
echo -e "     (coller la clé WG publique dans le champ dédié)"
echo -e "  2. Vérifier vmbr1 sur Proxmox : ip link show vmbr1"
echo -e "     Si absent : ssh root@${PROXMOX_IP} 'bash 03-setup-network.sh'"
echo -e "  3. Déployer instance Mailpiler : ssh root@${PROXMOX_IP} 'bash 02-deploy-client.sh'"
echo ""
