#!/usr/bin/env bash
# ====================================================================
# Agent Linux Abilor (one-shot) — RustDesk
# Installe RustDesk si absent (Debian/Ubuntu .deb), applique la config
# serveur Abilor, fixe un mot de passe permanent, récupère l'ID RustDesk,
# puis enregistre le poste dans le registre WordPress abilor.fr.
# But : contrôle à distance du poste Linux depuis la console Abilor.
#
# Usage (en root) :
#   curl -fsSL https://dl.abilor.fr/rustdesk/abilor-rustdesk-linux.sh | sudo bash
# Avec un mot de passe imposé (sinon généré) et/ou société/client :
#   curl -fsSL .../abilor-rustdesk-linux.sh | sudo ABILOR_SOCIETE="MOUCHAR" bash -s -- "MonMotDePasse"
# ====================================================================
set -u

REGISTER_URL="https://abilor.fr/wp-json/rustdesk/v1/register"
MYIP_URL="https://abilor.fr/wp-json/rustdesk/v1/myip"
RDK_SECRET="RDKing4Bf2Np9Qs6Tv3Wx8Zc5Md1Hk7Lr0Aj"          # secret INGEST (register only) — même que l'agent public
CONFIG_TOKEN="0nI9k0dRpWNsdTRWJmdvhHS0JVbUh2UUlVasBlYyEHRYtGdRhWb2I1KKNmUjNlI6ISeltmIsIiI6ISawFmIsIicm5icvxWaiFmLxMnbiojI5FGblJnIsIicm5icvxWaiFmLxMnbiojI0N3boJye"
RD_VERSION="1.4.7"                                          # version RustDesk installée si absent (alignée Windows)

SOCIETE="${ABILOR_SOCIETE:-}"
CLIENT="${ABILOR_CLIENT:-}"
WANT_PW="${1:-}"

log(){ echo "[abilor] $*"; }

# Désactive Wayland dans GDM pour que le poste démarre en X11 (capture RustDesk
# sans la fenêtre « Partager l'écran »). Prend effet au prochain démarrage/login.
# Renvoie 0 si appliqué/déjà OK, 1 si non applicable (pas de GDM).
force_x11_gdm() {
  local conf=""
  for c in /etc/gdm3/custom.conf /etc/gdm/custom.conf; do
    [ -f "$c" ] && conf="$c" && break
  done
  if [ -z "$conf" ]; then
    log "GDM introuvable (autre gestionnaire de connexion ?) — bascule X11 non appliquée automatiquement."
    return 1
  fi
  if grep -qiE '^[[:space:]]*WaylandEnable[[:space:]]*=[[:space:]]*false' "$conf"; then
    log "Wayland déjà désactivé dans $conf (X11 au prochain démarrage)."
    return 0
  fi
  cp -a "$conf" "${conf}.abilor.bak" 2>/dev/null || true
  if grep -qiE '^[[:space:]]*#?[[:space:]]*WaylandEnable[[:space:]]*=' "$conf"; then
    sed -i -E 's|^[[:space:]]*#?[[:space:]]*WaylandEnable[[:space:]]*=.*|WaylandEnable=false|I' "$conf"
  elif grep -qiE '^[[:space:]]*\[daemon\]' "$conf"; then
    sed -i -E 's|^[[:space:]]*\[daemon\][[:space:]]*$|[daemon]\nWaylandEnable=false|I' "$conf"
  else
    printf '\n[daemon]\nWaylandEnable=false\n' >> "$conf"
  fi
  log "Wayland désactivé dans GDM ($conf, sauvegarde ${conf}.abilor.bak)."
  return 0
}

[ "$(id -u)" = "0" ] || { log "À lancer en root (sudo)."; exit 1; }

# ---------- 1) localiser RustDesk ----------
RD="$(command -v rustdesk 2>/dev/null || true)"
if [ -z "$RD" ]; then
  for p in /usr/bin/rustdesk /usr/local/bin/rustdesk /opt/rustdesk/rustdesk; do
    [ -x "$p" ] && RD="$p" && break
  done
fi

# ---------- 2) installer RustDesk si absent (Debian/Ubuntu) ----------
if [ -z "$RD" ]; then
  log "RustDesk absent — installation du paquet .deb officiel v$RD_VERSION…"
  case "$(dpkg --print-architecture 2>/dev/null || uname -m)" in
    arm64|aarch64) DEBARCH="aarch64" ;;
    *)             DEBARCH="x86_64" ;;
  esac
  TMP="$(mktemp -d)"
  DEB="$TMP/rustdesk.deb"
  DEB_NAME="rustdesk-${RD_VERSION}-${DEBARCH}.deb"
  # 1) copie hébergée chez Abilor (fiable, version alignée), 2) repli release officielle GitHub
  if curl -fsSL "https://dl.abilor.fr/rustdesk/${DEB_NAME}" -o "$DEB" \
     || curl -fsSL "https://github.com/rustdesk/rustdesk/releases/download/${RD_VERSION}/${DEB_NAME}" -o "$DEB"; then
    apt-get update -y >/dev/null 2>&1 || true
    apt-get install -y "$DEB" >/dev/null 2>&1 || { dpkg -i "$DEB" >/dev/null 2>&1; apt-get -f install -y >/dev/null 2>&1; }
  else
    log "Échec du téléchargement de $DEB_NAME. Installez RustDesk puis relancez."; exit 1
  fi
  RD="$(command -v rustdesk 2>/dev/null || echo /usr/bin/rustdesk)"
  [ -x "$RD" ] || { log "RustDesk toujours introuvable après installation."; exit 1; }
fi
log "RustDesk = $RD"

# ---------- 3) démarrer le service RustDesk (IPC requis pour --config/--password/--get-id) ----------
systemctl enable --now rustdesk >/dev/null 2>&1 || { "$RD" --service >/dev/null 2>&1 & }
sleep 4

# ---------- 4) appliquer la config serveur Abilor ----------
if "$RD" --config "$CONFIG_TOKEN" >/dev/null 2>&1; then
  log "Config serveur Abilor appliquée."
else
  log "Config serveur : à vérifier (commande --config non confirmée)."
fi

# ---------- 5) mot de passe permanent ----------
if [ -n "$WANT_PW" ]; then
  PW="$WANT_PW"
else
  PW="$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 14)"
fi
for i in 1 2 3; do "$RD" --password "$PW" >/dev/null 2>&1 && break; sleep 2; done
log "Mot de passe permanent fixé."

# ---------- 6) ID RustDesk ----------
ID=""
for i in 1 2 3 4 5; do
  ID="$("$RD" --get-id 2>/dev/null | tr -dc '0-9')"
  [ -n "$ID" ] && break
  sleep 2
done
# repli : lire l'ID directement dans le fichier de config si --get-id muet
if [ -z "$ID" ]; then
  ID="$(grep -hoE "^id\s*=\s*'?[0-9]+'?" /root/.config/rustdesk/*.toml /home/*/.config/rustdesk/*.toml 2>/dev/null | grep -oE '[0-9]+' | head -1)"
fi
[ -z "$ID" ] && { log "ID RustDesk introuvable (le service RustDesk est-il démarré ?)."; exit 1; }
log "ID RustDesk = $ID"

# ---------- 7) contexte du poste ----------
HOST="$(hostname)"
IP="$(curl -fsSL "$MYIP_URL" 2>/dev/null | grep -oE '"ip"[: ]*"[^"]*"' | cut -d'"' -f4)"
if [ -n "$IP" ]; then MACHINE="$HOST ($IP)"; else MACHINE="$HOST"; fi
PRETTY="Linux"; [ -r /etc/os-release ] && PRETTY="$(. /etc/os-release; echo "${PRETTY_NAME:-Linux}")"
OS="$PRETTY ($(getconf LONG_BIT) bits)"

# type de session graphique (Wayland bloque la capture sans clic « Partager l'écran »)
SESSION_TYPE="${XDG_SESSION_TYPE:-}"
if [ -z "$SESSION_TYPE" ] && command -v loginctl >/dev/null 2>&1; then
  for s in $(loginctl list-sessions --no-legend 2>/dev/null | awk '{print $1}'); do
    t="$(loginctl show-session "$s" -p Type --value 2>/dev/null)"
    case "$t" in wayland|x11) SESSION_TYPE="$t"; break ;; esac
  done
fi

# ---------- 8) enregistrement dans le registre WordPress ----------
JSON="$(printf '{"machine":"%s","societe":"%s","client":"%s","id":"%s","password":"%s","arch":"%s","os":"%s","hostname":"%s"}' \
  "$MACHINE" "$SOCIETE" "$CLIENT" "$ID" "$PW" "$(uname -m)" "$OS" "$HOST")"
RESP="$(curl -fsS -X POST "$REGISTER_URL" -H 'Content-Type: application/json' -H "X-RDK-Secret: $RDK_SECRET" --data "$JSON" 2>&1)"
log "Réponse du registre : $RESP"

echo
log "================= RÉSUMÉ ================="
log "Machine       : $MACHINE"
log "OS            : $OS"
log "ID RustDesk   : $ID"
log "Mot de passe  : $PW"
log "Le poste est enregistré dans la console Abilor (double-clic = connexion)."
log "========================================="

# ---------- 9) Wayland -> bascule automatique en X11 ----------
if [ "$SESSION_TYPE" = "wayland" ]; then
  echo
  if [ "${ABILOR_NO_X11:-0}" = "1" ]; then
    log "Session WAYLAND détectée. Bascule X11 désactivée (ABILOR_NO_X11=1)."
    log "=> RustDesk demandera « Partager l'écran » à chaque connexion (clic requis sur le poste)."
  else
    log "Session WAYLAND détectée (RustDesk redemande « Partager l'écran » à chaque connexion)."
    if force_x11_gdm; then
      log ">>> BASCULE EN X11 PROGRAMMÉE : au prochain REDÉMARRAGE, le poste"
      log "    démarrera en X11 et RustDesk capturera l'écran SANS aucun clic."
      log "    -> Un REBOOT est nécessaire pour activer le contrôle 100% à distance."
    else
      log "SOLUTION manuelle : choisir « ... sur Xorg » sur l'écran de connexion,"
      log "ou désactiver Wayland dans votre gestionnaire de connexion."
    fi
  fi
elif [ "$SESSION_TYPE" = "x11" ]; then
  log "Session graphique : X11 (Xorg) — contrôle à distance OK sans clic."
fi

# ---------- 10) service résident Abilor (équivalent AbilorAgent Windows) ----------
# Daemon systemd : auto-synchro ID/mot de passe + actions à distance (poll 60 s).
# Désactivable avec ABILOR_NO_SERVICE=1.
if [ "${ABILOR_NO_SERVICE:-0}" = "1" ]; then
  log "Service résident non installé (ABILOR_NO_SERVICE=1)."
else
  echo
  log "Installation du service de maintenance Abilor…"
  case "$(uname -m)" in
    aarch64|arm64) AGENT_ARCH="arm64" ;;
    *)             AGENT_ARCH="amd64" ;;
  esac
  AGENT_URL="https://dl.abilor.fr/rustdesk/abilor-agent-linux-${AGENT_ARCH}"
  install -d -m 0755 /opt/abilor
  if curl -fsSL "$AGENT_URL" -o /opt/abilor/abilor-agent; then
    chmod 0755 /opt/abilor/abilor-agent
    # graine d'état : le service connaît d'emblée l'ID + mot de passe déjà posés
    # (évite un reset inutile au 1er passage)
    printf '{\n  "id": "%s",\n  "password": "%s"\n}\n' "$ID" "$PW" > /opt/abilor/state.json
    chmod 0600 /opt/abilor/state.json
    if /opt/abilor/abilor-agent >/dev/null 2>&1; then
      log "Service abilor-agent installé et démarré (poll 60 s, auto-synchro ID/mdp + actions)."
    else
      log "Service installé mais démarrage à vérifier (systemctl status abilor-agent)."
    fi
  else
    log "Téléchargement du service échoué ($AGENT_URL) — enrôlement OK, service non installé."
  fi
fi
