#!/bin/bash

# Author: CBillet
# Version: 1.1
# Date de création: 2024-10-30
# Contact: N/A

# Initialisation des variables
maxage=""
target_dir=""
pattern=""
exclude_patterns=()  # Nouveau tableau pour stocker les patterns d'exclusion
force_delete=false
verbose=true  # Mode verbose activé par défaut
command_id=$(date '+%Y%m%d%H%M%S')  # Génération d'un ID unique basé sur le timestamp
script_name=$(basename "$0")  # Nom du script
tag=SCRIPT # tag dans le logger

# Fonction de logging avec différenciation
log() {
    local message="$1"
    local mode="${2:-both}"  # Par défaut, log et affiche

    if [[ "$mode" == "log_only" ]]; then
        logger -t $tag "$(date '+%Y-%m-%d %H:%M:%S') [$script_name] [ID:$command_id] : $message"
    elif [[ "$mode" == "display_only" ]]; then
        $verbose && echo "$message"
    else # BOTH
        logger -t $tag "$(date '+%Y-%m-%d %H:%M:%S') [$script_name] [ID:$command_id] : $message"
        $verbose && echo "$message"
    fi
}

# Fonction d'affichage de l'aide
usage() {
    local width=$(tput cols)  # Obtient la largeur de la console
    local separator=$(printf '=%.0s' $(seq 1 $width))  # Génère une ligne de '=' de la largeur de la console

    cat << EOF
$separator

#################
### Help Page ###
#################

Script Name: $(basename "$0")

Author: Corentin Billet
Version: 1.1
Date de création: 2024-10-30
Contact: corentin.billet@galec.lecler

Description:
  Ce script supprime les fichiers plus anciens qu'un nombre de jours spécifié dans un répertoire cible, avec un filtre de nom.
  La version 1.1 ajoute la possibilité d'exclure certains fichiers en utilisant l'option -e ou --exclude.

Usage:
  $0 [OPTIONS]

Options:
  -m, --maxage <days>      Nombre maximum de jours avant suppression (0 pour inclure les fichiers du jour et d'avant). Ce paramètre est obligatoire.
  -p, --pattern <pattern>  Filtre pour les fichiers à supprimer, par exemple "*.log", "toto.*", ou "*" pour tous les fichiers. Ce paramètre est obligatoire.
  -d, --dir <directory>    Répertoire cible contenant les fichiers à supprimer. Ce paramètre est obligatoire.
  -e, --exclude <pattern>  Motif pour exclure certains fichiers de la suppression (peut être utilisé plusieurs fois).
  -f, --force              Supprime les fichiers sans confirmation.
  -q, --quiet              Mode silencieux, n'affiche aucun message de confirmation ou d'exécution.
  -h, --help               Affiche cette aide avec des exemples.

Exemples:
  $0 -m 30 -p "*.log" -d /var/logs/ -e "*.bak" -e "*old*"
    Supprime les fichiers .log plus vieux de 30 jours dans /var/logs, mais exclut les fichiers terminant par .bak ou contenant "old".

Description détaillée:
  Ce script utilise la commande 'find' pour identifier les fichiers dans le répertoire spécifié, en fonction de l'âge et du filtre de nom.
  Par défaut, le mode verbose est activé et affiche les messages de confirmation et d'exécution.
  Si l'option '-q' (quiet) est utilisée, aucun message n'est affiché à l'écran, mais toutes les actions sont enregistrées avec un ID unique
  basé sur le timestamp.

$separator

EOF
    exit 1
}

# Gestion des options avec getopts
log "Script de nettoyage '$script_name' démarré avec ID de commande : $command_id." "log_only"
while [[ "$#" -gt 0 ]]; do
    case "$1" in
        -m|--maxage)
            maxage="$2"
            shift 2
            log "Option maxage définie à $maxage jours." "log_only"
            ;;
        -p|--pattern)
            pattern="$2"
            shift 2
            log "Option pattern définie à '$pattern'." "log_only"
            ;;
        -d|--dir)
            target_dir="$2"
            shift 2
            log "Option directory définie à '$target_dir'." "log_only"
            ;;
        -e|--exclude)
            exclude_patterns+=("$2")
            shift 2
            log "Option exclude ajoutée pour exclure le motif '$2'." "log_only"
            ;;
        -f|--force)
            force_delete=true
            shift 1
            log "Option force activée, suppression sans confirmation." "log_only"
            ;;
        -q|--quiet)
            verbose=false  # Désactive l'affichage mais le logging est toujours actif
            shift 1
            log "Option quit activée, silence sur le prompte." "log_only"
            ;;
        -h|--help)
            usage
            ;;
        *)
            log "Option inconnue : $1" "log_only"
            usage
            ;;
    esac
done

# Vérification que toutes les options requises sont définies
if [[ -z "$maxage" || -z "$target_dir" || -z "$pattern" ]]; then
    log "Erreur : toutes les options -m, -p, et -d sont obligatoires." "display_only"
    log "Erreur : toutes les options -m, -p, et -d ne sont pas complétées. Arrêt script." "display_only"
    usage
fi

# Construction de la commande 'find' avec exclusion
find_cmd="find \"$target_dir\" -type f \( -mtime -1 -o -mtime +$maxage \) -name \"$pattern\""

# Ajout des conditions d'exclusion à la commande find
for excl in "${exclude_patterns[@]}"; do
    find_cmd+=" ! -name \"$excl\""
done

log "Commande find construite : $find_cmd" "log_only"

# Exécution de la commande find pour obtenir les fichiers à supprimer
files_to_delete=$(eval $find_cmd)

# Vérifier s'il y a des fichiers à supprimer
if [[ -z "$files_to_delete" ]]; then
    log "Aucun fichier trouvé correspondant aux critères : pattern='$pattern', maxage='$maxage' jours." "both"
    exit 0
fi

# Affichage des fichiers si verbose est activé
if [[ "$verbose" = true ]]; then
    log "Les fichiers suivants seront supprimés :" "display_only"
    for file in $files_to_delete; do
        file_date=$(stat -c %y "$file" | cut -d'.' -f1)
        log "$file : $file_date" "display_only"
    done
fi

# Si 'force_delete' est false, demander confirmation
if [[ "$force_delete" = false ]]; then
    read -p "Êtes-vous sûr de vouloir supprimer ces fichiers ? (o/N) : " confirmation
    if [[ "$confirmation" != "o" && "$confirmation" != "O" ]]; then
        log "Opération annulée par l'utilisateur." "both"
        exit 0
    fi
fi

# Suppression des fichiers
log "Suppression des fichiers en cours..." "both"
for file in $files_to_delete; do
    rm -f "$file"
    log "Fichier supprimé : $file" "both"
done

# Message de succès final
log "Opération de nettoyage terminée. Les fichiers correspondant à '$pattern' et plus anciens que $maxage jours dans $target_dir ont été supprimés." "both"
