#!/usr/bin/env bash
#
# setup-new-machine.sh
# Script d'initialisation pour une nouvelle machine Linux (Debian/Ubuntu)
# - Installe Docker + Docker Compose (et les met à jour)
# - Installe spookdev-motd et personnalise le MOTD
# - Ajoute une section ZFS optionnelle au MOTD (avec installation des paquets zfs si demandé)
# - Active force_color_prompt=yes dans /root/.bashrc
#
# À lancer en root (ou via sudo) sur une machine fraîchement installée.

set -euo pipefail

# ------------------------------------------------------------------
# Vérifications de base
# ------------------------------------------------------------------
if [ "$(id -u)" -ne 0 ]; then
    echo "Ce script doit être exécuté en root (sudo $0)." >&2
    exit 1
fi

log() { echo -e "\033[1;32m[setup]\033[0m $*"; }
warn() { echo -e "\033[1;33m[setup]\033[0m $*"; }
err() { echo -e "\033[1;31m[setup]\033[0m $*" >&2; }

# Empêche apt/debconf d'ouvrir des prompts interactifs (ex: keyboard-configuration)
# indispensable en usage automatisé / curl | bash, où il n'y a pas de vrai terminal utilisable par ncurses.
export DEBIAN_FRONTEND=noninteractive
export DEBCONF_NONINTERACTIVE_SEEN=true
APT_OPTS=(-y -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-confdef")

# ------------------------------------------------------------------
# 1. Mise à jour du système
# ------------------------------------------------------------------
log "Mise à jour des paquets système..."
apt-get update -y
apt-get upgrade "${APT_OPTS[@]}"

# ------------------------------------------------------------------
# 2. Installation de Docker + Docker Compose
# ------------------------------------------------------------------
if ! command -v docker &>/dev/null; then
    log "Installation de Docker..."
    apt-get install "${APT_OPTS[@]}" ca-certificates curl gnupg
    install -m 0755 -d /etc/apt/keyrings

    # Détection de la distro (debian ou ubuntu)
    . /etc/os-release
    DISTRO_ID="$ID"

    curl -fsSL "https://download.docker.com/linux/${DISTRO_ID}/gpg" -o /etc/apt/keyrings/docker.asc
    chmod a+r /etc/apt/keyrings/docker.asc

    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/${DISTRO_ID} \
      $(. /etc/os-release && echo "${VERSION_CODENAME}") stable" | \
      tee /etc/apt/sources.list.d/docker.list > /dev/null

    apt-get update -y
    apt-get install "${APT_OPTS[@]}" docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    systemctl enable --now docker
    log "Docker installé : $(docker --version)"
else
    log "Docker déjà présent, mise à jour..."
    apt-get install "${APT_OPTS[@]}" --only-upgrade docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin || true
fi

log "Docker Compose : $(docker compose version 2>/dev/null || echo 'non disponible')"

# ------------------------------------------------------------------
# 3. Option ZFS (choix interactif)
# ------------------------------------------------------------------
INSTALL_ZFS="n"
if [ -r /dev/tty ]; then
    read -r -p "Installer le support ZFS (paquets zfsutils-linux + section MOTD dédiée) ? [y/N] " ans < /dev/tty
    case "$ans" in
        [yY]*) INSTALL_ZFS="y" ;;
        *) INSTALL_ZFS="n" ;;
    esac
else
    warn "Pas de terminal interactif détecté (/dev/tty inaccessible), ZFS non installé par défaut (utilisez --with-zfs pour forcer)."
fi

# Permet de forcer via argument --with-zfs / --no-zfs (utile en non-interactif)
for arg in "$@"; do
    case "$arg" in
        --with-zfs) INSTALL_ZFS="y" ;;
        --no-zfs) INSTALL_ZFS="n" ;;
    esac
done

if [ "$INSTALL_ZFS" = "y" ]; then
    log "Installation des paquets ZFS..."
    apt-get install "${APT_OPTS[@]}" zfsutils-linux
else
    log "ZFS non installé (section MOTD ZFS ignorée)."
fi

# ------------------------------------------------------------------
# 4. Installation de spookdev-motd
# ------------------------------------------------------------------
log "Installation de spookdev-motd..."
curl -L https://raw.githubusercontent.com/NeonWizard/spookdev-motd/master/install.sh | sh

# Remplace le banner ASCII "spookydev" (toilet) par un simple saut de ligne :
# on ne veut pas le texte, mais le saut de ligne évite que la première ligne
# du MOTD ne s'accroche à la fin de la ligne "password:" de SSH.
cat > /etc/update-motd.d/00-header << 'EOF'
#!/bin/bash
echo ""
EOF
chmod +x /etc/update-motd.d/00-header

# ------------------------------------------------------------------
# 5. Personnalisation des couleurs
# ------------------------------------------------------------------
log "Configuration des couleurs du MOTD..."
mkdir -p /etc/update-motd.d
cat > /etc/update-motd.d/colors.txt << 'EOF'
NC='\033[0m'
#DEFAULT_COLOR='\e[38;5;34m'
#TITLE_COLOR='\e[38;5;75m'
#TEXT_COLOR='\e[38;5;83m'

DEFAULT_COLOR=$NC
TITLE_COLOR=$NC
#TEXT_COLOR='\e[38;5;196m'
TEXT_COLOR='\033[1;32m'
EOF

# ------------------------------------------------------------------
# 6. Script MOTD Docker
# ------------------------------------------------------------------
log "Ajout du script MOTD Docker (10-docker)..."
cat > /etc/update-motd.d/10-docker << 'EOF'
#!/usr/bin/env bash

source /etc/update-motd.d/colors.txt

if command -v docker &>/dev/null; then
    RUNNING_CONTAINERS=$(docker ps -q | wc -l)
    TOTAL_CONTAINERS=$(docker ps -a -q | wc -l)
    echo -e " Docker containers...: ${TEXT_COLOR}$RUNNING_CONTAINERS ${NC}/ ${TEXT_COLOR}$TOTAL_CONTAINERS${NC} running:${NC}"
    if [ "$RUNNING_CONTAINERS" -gt 0 ]; then
      docker ps --format "   • {{.Names}}" | while read line; do printf "   %s\n" "$line"; done
    fi
  else
    echo -e "${TITLE_COLOR} Docker..............: not installed${NC}"
fi
EOF
chmod +x /etc/update-motd.d/10-docker

# ------------------------------------------------------------------
# 7. Script MOTD ZFS (uniquement si installé)
# ------------------------------------------------------------------
if [ "$INSTALL_ZFS" = "y" ]; then
    log "Ajout du script MOTD ZFS (11-zfs)..."
    cat > /etc/update-motd.d/11-zfs << 'EOF'
#!/usr/bin/env bash
source /etc/update-motd.d/colors.txt

if ! command -v zpool &>/dev/null; then
    echo -e " ZFS.................: not installed"
    exit 0
fi

POOL="tank"

if ! zpool list "$POOL" &>/dev/null 2>&1; then
    echo -e " ZFS pool '$POOL'.....: ${RED}not found${NC}"
    exit 0
fi

# Récupère les infos du pool
STATUS=$(zpool list -H -o health "$POOL")
SIZE=$(zpool list -H -o size "$POOL")
USED=$(zpool list -H -o allocated "$POOL")
FREE=$(zpool list -H -o free "$POOL")
FRAG=$(zpool list -H -o frag "$POOL")

# Couleur selon le status
case "$STATUS" in
    ONLINE)   STATUS_COLOR="${TEXT_COLOR}" ;;   # vert
    DEGRADED) STATUS_COLOR='\033[1;33m'   ;;   # jaune
    FAULTED)  STATUS_COLOR='\033[1;31m'   ;;   # rouge
    *)        STATUS_COLOR='\033[1;31m'   ;;
esac

echo -e " ZFS pool '$POOL'....: ${STATUS_COLOR}${STATUS}${NC} — Used: ${TEXT_COLOR}${USED}${NC} / ${TEXT_COLOR}${SIZE}${NC} | Free: ${TEXT_COLOR}${FREE}${NC} | Frag: ${TEXT_COLOR}${FRAG}${NC}"

# Affiche les vdevs avec leur état
zpool status "$POOL" | awk '
/^\t  (mirror|raidz|sda|sdb|sdc|nvme|disk|ata)/ {
    gsub(/^\t/, "")
    name=$1; state=$2
    color="\033[1;32m"
    if (state == "DEGRADED") color="\033[1;33m"
    if (state == "FAULTED" || state == "OFFLINE") color="\033[1;31m"
    printf "   • %-20s %s%s\033[0m\n", name, color, state
}'
EOF
    chmod +x /etc/update-motd.d/11-zfs
else
    # Au cas où un script existant traînerait d'une install précédente
    rm -f /etc/update-motd.d/11-zfs
fi

# ------------------------------------------------------------------
# 8. Script MOTD updates (09-updates), filtré pour ne rien afficher
#    quand il ne reste que le bruit standard d'Ubuntu/ESM/Pro.
#    (le filtre d'origine ne matchait que "mise à jour" au singulier,
#    corrigé ici pour matcher aussi le pluriel "mises à jour")
# ------------------------------------------------------------------
log "Configuration du script MOTD updates (09-updates)..."
cat > /etc/update-motd.d/09-updates << 'EOF'
#!/bin/bash
stamp="/var/lib/update-notifier/updates-available"
[ ! -r "$stamp" ] || cat "$stamp" | grep -v -i -E "esm|pro status|ubuntu\.com|activez|visitez|maintenance|mises? à jour|update" | grep -v '^$' | head -c -1
find $stamp -newermt 'now-7 days' 2> /dev/null | grep -q -m 1 '.' || /usr/share/update-notifier/notify-updates-outdated
EOF
chmod +x /etc/update-motd.d/09-updates

# ------------------------------------------------------------------
# 9. Modification du bashrc root (force_color_prompt=yes)
# ------------------------------------------------------------------
BASHRC="/root/.bashrc"
if [ -f "$BASHRC" ]; then
    log "Activation de force_color_prompt=yes dans $BASHRC..."
    if grep -q '^force_color_prompt=yes' "$BASHRC"; then
        log "force_color_prompt déjà activé."
    elif grep -q '#force_color_prompt=yes' "$BASHRC"; then
        sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' "$BASHRC"
    else
        # Insère la ligne juste avant le bloc "if [ -n "$force_color_prompt" ]"
        sed -i '/^if \[ -n "\$force_color_prompt" \]; then/i force_color_prompt=yes' "$BASHRC"
    fi

    # Certains bashrc root ne sont pas le skeleton standard Debian/Ubuntu et
    # utilisent le code couleur vert (01;32m, normalement réservé aux users)
    # au lieu du rouge (01;31m) attendu pour root. On force le rouge.
    if grep -q '01;32m' "$BASHRC"; then
        log "Correction du code couleur du prompt root (vert -> rouge)..."
        sed -i 's/01;32m/01;31m/g' "$BASHRC"
    fi
else
    warn "$BASHRC introuvable, création d'un bashrc minimal avec force_color_prompt=yes."
    cat > "$BASHRC" << 'EOF'
force_color_prompt=yes
[ -z "$PS1" ] && return
HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
HISTSIZE=1000
HISTFILESIZE=2000
shopt -s checkwinsize
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac
if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        color_prompt=yes
    else
        color_prompt=
    fi
fi
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi
EOF
fi

# ------------------------------------------------------------------
# 10. Exécution du MOTD pour test
# ------------------------------------------------------------------
log "Test du MOTD :"
run-parts /etc/update-motd.d/ || true

log "Terminé. Reconnecte-toi (ou 'exec bash') pour voir le nouveau prompt et le MOTD."
