#!/bin/bash

# Script de configuration de sudoers
# Nécessite les privilèges root

set -e  # Arrêt en cas d'erreur

# Couleurs pour l'affichage
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

SUDOERS_FILE="/etc/sudoers.d/99-admins"
BACKUP_DIR="/root/sudoers_backup_$(date +%Y%m%d_%H%M%S)"
UNATTENDED=false

# Fonction d'affichage
print_info() { echo -e "${BLUE}ℹ${NC} $1"; }
print_success() { echo -e "${GREEN}✅${NC} $1"; }
print_warning() { echo -e "${YELLOW}⚠️${NC} $1"; }
print_error() { echo -e "${RED}❌${NC} $1"; }

# Vérification des privilèges sudo/root
check_root() {
    if [ "$EUID" -ne 0 ]; then 
        print_error "Ce script doit être exécuté avec sudo ou en tant que root"
        echo "Usage : sudo $0 [install|uninstall|force] [--unattended]"
        exit 1
    fi
}

# Fonction de sauvegarde
backup_sudoers() {
    print_info "Création d'une sauvegarde dans $BACKUP_DIR"
    mkdir -p "$BACKUP_DIR"
    
    if [ -d "/etc/sudoers.d" ] && [ "$(ls -A /etc/sudoers.d 2>/dev/null)" ]; then
        cp -r /etc/sudoers.d/* "$BACKUP_DIR/" 2>/dev/null
        print_success "Sauvegarde créée"
    else
        print_warning "Aucun fichier à sauvegarder"
    fi
}

# Fonction pour demander confirmation
ask_confirmation() {
    local question="$1"
    local default="${2:-N}"
    
    if [ "$UNATTENDED" = true ]; then
        print_info "Mode non-interactif : réponse automatique 'Oui'"
        return 0
    fi
    
    if [ "$default" = "Y" ]; then
        read -p "$question [O/n] " -n 1 -r
    else
        read -p "$question [o/N] " -n 1 -r
    fi
    echo
    
    if [ "$default" = "Y" ]; then
        [[ $REPLY =~ ^[Nn]$ ]] && return 1 || return 0
    else
        [[ $REPLY =~ ^[OoYy]$ ]] && return 0 || return 1
    fi
}

# Fonction d'installation
install_config() {
    print_info "🔧 Configuration de sudoers en cours..."
    
    # Vérifier si le fichier existe déjà
    if [ -f "$SUDOERS_FILE" ]; then
        print_warning "Le fichier $SUDOERS_FILE existe déjà"
        if ! ask_confirmation "Voulez-vous le remplacer ?"; then
            print_info "Installation annulée"
            exit 0
        fi
    fi
    
    # Sauvegarde de sécurité
    backup_sudoers
    
    # Suppression du contenu de /etc/sudoers.d
    print_info "Suppression du contenu de /etc/sudoers.d..."
    rm -f /etc/sudoers.d/*
    
    # Création du fichier temporaire
    TEMP_FILE=$(mktemp)
    
    cat > "$TEMP_FILE" << 'EOF'
# --- Admin user principal ---
dbi ALL=(ALL) ALL

# --- Logging sudo ---
Defaults logfile="/var/log/sudo.log"
Defaults loglinelen=0
Defaults log_input
Defaults log_output
Defaults use_pty

# --- Sécurité ---
Defaults !requiretty
Defaults timestamp_timeout=15

# --- Variables utiles ---
Defaults env_keep += "TS_AUTHKEY TS_CERT*"
Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY"

# --- Silence ---
Defaults !lecture
Defaults !mail_badpass
EOF
    
    # Vérification avec visudo
    print_info "Vérification de la syntaxe avec visudo..."
    if visudo -c -f "$TEMP_FILE" > /dev/null 2>&1; then
        # Déplacer le fichier validé
        mv "$TEMP_FILE" "$SUDOERS_FILE"
        
        # Définition des permissions appropriées
        chmod 0440 "$SUDOERS_FILE"
        chown root:root "$SUDOERS_FILE"
        
        print_success "Configuration validée par visudo"
    else
        print_error "Erreur de syntaxe détectée par visudo !"
        print_info "Restauration de la sauvegarde..."
        rm -f "$TEMP_FILE"
        
        if [ -d "$BACKUP_DIR" ] && [ "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then
            cp -r "$BACKUP_DIR"/* /etc/sudoers.d/
            print_success "Sauvegarde restaurée"
        fi
        exit 1
    fi
    
    # Création du fichier de log s'il n'existe pas
    touch /var/log/sudo.log
    chmod 600 /var/log/sudo.log
    chown root:root /var/log/sudo.log
    
    print_success "Configuration sudoers appliquée avec succès !"
    print_info "📁 Sauvegarde disponible dans : $BACKUP_DIR"
    print_info "📄 Nouveau fichier : $SUDOERS_FILE"
    
    # Vérification finale avec visudo sur l'ensemble
    print_info "Vérification finale de la configuration globale..."
    if visudo -c > /dev/null 2>&1; then
        print_success "Configuration globale validée !"
    else
        print_error "Attention : Problème détecté dans la configuration globale"
    fi
}

# Fonction de désinstallation
uninstall_config() {
    print_info "🗑️  Désinstallation de la configuration sudoers..."
    
    # Sauvegarde avant désinstallation
    backup_sudoers
    
    if [ -f "$SUDOERS_FILE" ]; then
        print_info "Suppression de $SUDOERS_FILE"
        rm -f "$SUDOERS_FILE"
        print_success "Fichier supprimé"
    else
        print_warning "Le fichier $SUDOERS_FILE n'existe pas"
    fi
    
    # Nettoyage du fichier de log (optionnel)
    if [ -f "/var/log/sudo.log" ]; then
        if ask_confirmation "Voulez-vous également supprimer /var/log/sudo.log ?"; then
            rm -f /var/log/sudo.log
            print_success "Fichier de log supprimé"
        fi
    fi
    
    print_success "Désinstallation terminée !"
    print_info "📁 Sauvegarde disponible dans : $BACKUP_DIR"
    
    if [ "$UNATTENDED" = false ]; then
        print_warning "Note : Assurez-vous d'avoir un autre moyen d'accès sudo configuré"
    fi
}

# Fonction d'installation forcée
force_install() {
    print_warning "🔨 Installation forcée en cours (sans confirmation)..."
    
    # Sauvegarde de sécurité
    backup_sudoers
    
    # Suppression du contenu de /etc/sudoers.d
    print_info "Suppression du contenu de /etc/sudoers.d..."
    rm -f /etc/sudoers.d/*
    
    # Création du fichier temporaire
    TEMP_FILE=$(mktemp)
    
    cat > "$TEMP_FILE" << 'EOF'
# --- Admin user principal ---
dbi ALL=(ALL) ALL

# --- Logging sudo ---
Defaults logfile="/var/log/sudo.log"
Defaults loglinelen=0
Defaults log_input
Defaults log_output
Defaults use_pty

# --- Sécurité ---
Defaults !requiretty
Defaults timestamp_timeout=15

# --- Variables utiles ---
Defaults env_keep += "TS_AUTHKEY TS_CERT*"
Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY"

# --- Silence ---
Defaults !lecture
Defaults !mail_badpass
EOF
    
    # Vérification avec visudo
    print_info "Vérification de la syntaxe avec visudo..."
    if visudo -c -f "$TEMP_FILE" > /dev/null 2>&1; then
        mv "$TEMP_FILE" "$SUDOERS_FILE"
        chmod 0440 "$SUDOERS_FILE"
        chown root:root "$SUDOERS_FILE"
        print_success "Configuration validée par visudo"
    else
        print_error "Erreur de syntaxe détectée par visudo !"
        rm -f "$TEMP_FILE"
        
        if [ -d "$BACKUP_DIR" ] && [ "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then
            cp -r "$BACKUP_DIR"/* /etc/sudoers.d/
            print_success "Sauvegarde restaurée"
        fi
        exit 1
    fi
    
    # Création du fichier de log
    touch /var/log/sudo.log
    chmod 600 /var/log/sudo.log
    chown root:root /var/log/sudo.log
    
    print_success "Installation forcée terminée !"
    print_info "📁 Sauvegarde disponible dans : $BACKUP_DIR"
    
    # Vérification finale
    print_info "Vérification finale de la configuration globale..."
    if visudo -c > /dev/null 2>&1; then
        print_success "Configuration globale validée !"
    fi
}

# Affichage de l'aide
show_help() {
    cat << EOF
Usage: sudo $0 [OPTION] [--unattended]

Options:
  install           Installer la configuration (demande confirmation si existe)
  force, -f         Forcer l'installation sans confirmation
  uninstall         Désinstaller la configuration
  help, -h          Afficher cette aide

Flags:
  --unattended, -y  Mode non-interactif (répond automatiquement 'Oui' à toutes les questions)
  --quiet, -q       Mode silencieux (minimal output)

Exemples:
  sudo $0 install
  sudo $0 install --unattended
  sudo $0 force
  sudo $0 uninstall -y
  sudo $0 install --unattended --quiet

Description:
  Ce script configure les règles sudoers pour l'utilisateur 'dbi' avec
  logging complet et paramètres de sécurité.
  
  En mode --unattended :
  - Aucune question interactive
  - Écrase automatiquement les fichiers existants
  - Supprime les logs lors de la désinstallation
  - Idéal pour l'automatisation et les déploiements

EOF
}

# Analyse des arguments
COMMAND=""
QUIET=false

while [[ $# -gt 0 ]]; do
    case $1 in
        install|uninstall|force|-f|--force|help|-h|--help)
            COMMAND="$1"
            shift
            ;;
        --unattended|-y|--yes)
            UNATTENDED=true
            shift
            ;;
        --quiet|-q)
            QUIET=true
            shift
            ;;
        *)
            print_error "Option inconnue : $1"
            show_help
            exit 1
            ;;
    esac
done

# Rediriger la sortie en mode silencieux
if [ "$QUIET" = true ]; then
    exec 3>&1
    exec 1>/dev/null
fi

# Valeur par défaut
COMMAND="${COMMAND:-install}"

# Programme principal
check_root

if [ "$UNATTENDED" = true ]; then
    print_info "🤖 Mode non-interactif activé"
fi

case "$COMMAND" in
    install)
        install_config
        ;;
    force|-f|--force)
        force_install
        ;;
    uninstall|remove)
        uninstall_config
        ;;
    help|-h|--help)
        show_help
        exit 0
        ;;
    *)
        print_error "Option inconnue : $COMMAND"
        show_help
        exit 1
        ;;
esac

# Restaurer la sortie en mode silencieux
if [ "$QUIET" = true ]; then
    exec 1>&3 3>&-
    echo "✅ Opération terminée avec succès"
else
    print_success "🎉 Opération terminée !"
fi
