#!/usr/bin/env bash
set -euo pipefail

# ── Paramètres ────────────────────────────────────────────────────────────────
SUBNET="192.168.10.0/24"
REMOTE_HOST="ket.inxs.me"
REMOTE_DIR="/myshares/shared/upload/inventory/tailscale_net_update"

SERVICE="tailscale_net_update.service"
TIMER="tailscale_net_update.timer"

LOG_DIR="/var/log"
HOST="$(hostname -s || hostname)"
TS="$(date +'%Y%m%d-%H%M%S')"
LOGFILE="${LOG_DIR}/${HOST}-tailscale_net_update-${TS}.log"
# ─────────────────────────────────────────────────────────────────────────────

log() {
  echo "[$(date +'%F %T')] $*" | tee -a "$LOGFILE"
  logger -t cleanup_tailscale_net_update "$*"
}

need() {
  command -v "$1" >/dev/null 2>&1 || { log "❌ Missing command: $1"; exit 1; }
}

unit_path() {
  local unit="$1"
  systemctl show "$unit" -p FragmentPath 2>/dev/null | awk -F= '/FragmentPath=/{print $2}'
}

purge_unit() {
  local unit="$1"
  if systemctl list-unit-files | awk '{print $1}' | grep -Fxq "$unit"; then
    log "Unit file registered: $unit"
  else
    log "Unit not registered: $unit"
  fi

  if systemctl is-active --quiet "$unit"; then
    log "Stopping $unit"
    systemctl stop "$unit" 2>&1 | tee -a "$LOGFILE"
  else
    log "$unit not active"
  fi

  if systemctl is-enabled --quiet "$unit"; then
    log "Disabling $unit"
    systemctl disable "$unit" 2>&1 | tee -a "$LOGFILE"
  else
    log "$unit not enabled"
  fi

  # Mask (évite ré‑enable accidentel avant suppression)
  log "Masking $unit"
  systemctl mask "$unit" 2>&1 | tee -a "$LOGFILE" || true

  # Supprimer le fichier d’unité si présent
  local path
  path="$(unit_path "$unit" || true)"
  if [[ -n "${path:-}" && -e "$path" ]]; then
    log "Removing unit file: $path"
    rm -f "$path"
  else
    for guess in "/etc/systemd/system/$unit" "/lib/systemd/system/$unit" "/usr/lib/systemd/system/$unit"; do
      [[ -e "$guess" ]] && { log "Removing unit file (guessed): $guess"; rm -f "$guess"; }
    done
  fi
}

# ── Pré‑checks ───────────────────────────────────────────────────────────────
: >"$LOGFILE" && chmod 640 "$LOGFILE"
need systemctl
need rsync
need ssh
need ip

log "── Cleanup start on host: $HOST ──"

# ── 1) Purge service & timer ────────────────────────────────────────────────
purge_unit "$TIMER"
purge_unit "$SERVICE"

log "systemctl daemon-reload"
systemctl daemon-reload 2>&1 | tee -a "$LOGFILE"

# ── 2) Nettoyage des routes et ip rules posées par l'ancien script ──────────
log "Checking for bad routes to ${SUBNET} via tailscale…"

# Supprime routes via Tailscale (quel que soit le gateway 100.x)
BAD_ROUTES="$(ip route show "$SUBNET" || true)"
if [[ -n "$BAD_ROUTES" ]]; then
  while read -r line; do
    [[ -z "$line" ]] && continue
    if grep -Eq 'dev[[:space:]]+tailscale0' <<<"$line"; then
      log "Deleting route: $line"
      # Tente plusieurs formes de suppression pour couvrir toutes variantes
      ip route del $SUBNET 2>/dev/null || true
      # extra: si via <ip> onlink était posé
      via_ip="$(sed -nE 's/.*via[[:space:]]+([0-9.]+).*/\1/p' <<<"$line" || true)"
      [[ -n "${via_ip:-}" ]] && ip route del "$SUBNET" via "$via_ip" dev tailscale0 2>/dev/null || true
    fi
  done <<<"$BAD_ROUTES"
else
  log "No existing route entries for $SUBNET"
fi

# Supprimer la rule prioritaire 2500 si présente
if ip rule show | grep -Fq "to ${SUBNET} lookup main"; then
  # Essaie avec la priorité connue (celle posée par l'ancien script)
  if ip rule show | grep -Fq "2500:	from all to ${SUBNET} lookup main"; then
    log "Deleting ip rule: priority 2500 to ${SUBNET} lookup main"
    ip rule del to "$SUBNET" priority 2500 2>/dev/null || true
  else
    # Fallback: supprime toute règle "to SUBNET lookup main" (rare)
    log "Deleting ip rule(s) matching: to ${SUBNET} lookup main"
    # On identifie les priorités et on supprime une par une
    while read -r pr; do
      [[ -z "$pr" ]] && continue
      log "Deleting ip rule priority $pr"
      ip rule del priority "$pr" 2>/dev/null || true
    done < <(ip rule | awk -v sn="$SUBNET" '$0 ~ sn && $0 ~ /lookup main/ {print $1}' | sed 's/://')
  fi
else
  log "No ip rule for ${SUBNET} → lookup main"
fi

ip route flush cache || true

# ── 3) Assurer la “bonne” route LAN locale si l’hôte est dans le LAN ────────
# Détecter l’interface qui porte une IP dans 192.168.10.0/24
LAN_LINE="$(ip -o -4 addr show to "$SUBNET" || true)"
if [[ -n "$LAN_LINE" ]]; then
  # Exemple de ligne: "7: vmbr0    inet 192.168.10.5/24 brd 192.168.10.255 scope global vmbr0"
  LAN_IFACE="$(awk '{print $2}' <<<"$LAN_LINE")"
  LAN_IFACE="${LAN_IFACE%:}" # retire un éventuel ':' à droite
  log "Detected local LAN iface for ${SUBNET}: ${LAN_IFACE}"

  CURRENT_ROUTE="$(ip route show "$SUBNET" || true)"
  if [[ "$CURRENT_ROUTE" == *"dev ${LAN_IFACE}"* ]]; then
    log "Good route already present: ${CURRENT_ROUTE}"
  else
    DESIRED="ip route replace ${SUBNET} dev ${LAN_IFACE} scope link metric 1"
    log "Applying good local route: ${DESIRED}"
    $DESIRED
    ip route flush cache || true
    log "Route applied."
  fi
else
  log "Host is NOT on ${SUBNET}; no local LAN route will be created."
fi

# ── 4) Post‑checks ──────────────────────────────────────────────────────────
log "Post-checks:"
log "  ip rule:"
ip rule | tee -a "$LOGFILE"
log "  ip route show ${SUBNET}:"
ip route show "$SUBNET" | tee -a "$LOGFILE" || true

# ── 5) Synchronisation du log vers ket ──────────────────────────────────────
log "Syncing log to ${REMOTE_HOST}:${REMOTE_DIR}/"
RSYNC_PATH="mkdir -p ${REMOTE_DIR} && rsync"
rsync -av --rsync-path "$RSYNC_PATH" "$LOGFILE" "${REMOTE_HOST}:${REMOTE_DIR}/" 2>&1 | tee -a "$LOGFILE"

log "── Cleanup done ──"
echo "Log written to: $LOGFILE"

