#! /bin/bash

# Simple script to migrate classes
# Copyright (C) 2026 FUSS Project <info@fuss.bz.it>
# Author: Claudio Cavalli <ccavalli@fuss.bz.it>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


exec > >(tee migrate_classes.log) 2>&1

# ==========================================================
# IMPOSTAZIONE DRY-RUN (L'INTERRUTTORE)
# ==========================================================
# Imposta a "true" per simulare, "false" per eseguire davvero
DRY_RUN=false

if [ "$DRY_RUN" = true ]; then
    echo "***************************************************"
    echo "  MODALITÀ DRY-RUN ATTIVA (SIMULAZIONE)            "
    echo "  Nessuna modifica verrà apportata al sistema.     "
    echo "***************************************************"
    sleep 2
fi

# Funzione di supporto per eseguire i comandi o solo stamparli
run() {
    if [ "$DRY_RUN" = true ]; then
        echo -e "\t[SIMULAZIONE] Eseguirei: $@"
    else
        "$@"
    fi
}
# ==========================================================
#Creiamo prima una copia di ldap
# LDAP save
run slapcat -l ldap-dump.ldif

get_confirmation() {
    while true; do
        echo -e "$1\n(yes/no): "
        read choice
        case $choice in
            [Yy]* ) return 0;;
            [Nn]* ) return 1;;
            * ) echo "Please answer 'yes' or 'no'.";;
        esac
    done
}

if [ -s classes_mapping.csv ]; then
    declare -A classi
    while IFS=, read -r OLDPATH NEWPATH
    do
        OLDPATH=$(echo "$OLDPATH" | tr -d '\r' | xargs)
        NEWPATH=$(echo "$NEWPATH" | tr -d '\r' | xargs)
        classi[$OLDPATH]=$NEWPATH
    done < classes_mapping.csv

    echo "Controllo esistenza/creazione cartelle di destinazione"
    for newpath in "${classi[@]}"; do
        run mkdir -p "$newpath"
    done
else
    echo "⚠️ Il file \"classes_mapping.csv\" non esiste!"
    sleep 5
    exit 1   
fi

if [ -s groups_mapping.csv ]; then
    declare -A gruppi
    while IFS=, read -r OLDGROUP NEWGROUP
    do
        OLDGROUP=$(echo "$OLDGROUP" | tr -d '\r' | xargs)
        NEWGROUP=$(echo "$NEWGROUP" | tr -d '\r' | xargs)
        gruppi[$OLDGROUP]=$NEWGROUP
    done < groups_mapping.csv

    echo " Controllo gruppi secondari in LDAP..."
    for newgroup in "${gruppi[@]}"; do
        if smbldap-groupshow "$newgroup" >/dev/null 2>&1; then
            echo "✅ Gruppo $newgroup già presente"
        else
            echo "➕ Creo gruppo mancante: $newgroup"
            run smbldap-groupadd "$newgroup"
        fi
    done
    echo "✅ Controllo completato."
else
    if get_confirmation "⚠️ Il file \"groups_mapping.csv\" non esiste! \nVuoi proseguire?"; then
        echo "✅Prosegui"
    else
        exit 1
    fi
fi

GRUPPO_PRIMARIO=studenti
if get_confirmation "Il gruppo primario degli utenti da spostare è \"$GRUPPO_PRIMARIO\"?"; then
    echo "Gruppo scelto: $GRUPPO_PRIMARIO"
else
    echo "Inserisci il gruppo primario degli utenti da spostare."
    read GRUPPO_PRIMARIO
    if get_confirmation "Confermi che il gruppo primario degli utenti da spostare è \"$GRUPPO_PRIMARIO\"?"; then
        echo "OK"
    else
        exit 1
    fi
fi

CARTELLA_COMUNE=00-Comune
if get_confirmation "Le classi hanno una CARTELLA_COMUNE?"; then
    if get_confirmation "Il nome della cartella comune è \"$CARTELLA_COMUNE\"?"; then
        echo "OK"
    else
        echo "Inserisci il nome della cartella comune."
        read CARTELLA_COMUNE
        if get_confirmation "Confermi che il nome della cartella comune è \"$CARTELLA_COMUNE\"?"; then
            echo "OK"
        else
            echo "⚠️ Non hai scelto il nome della cartella comune!"
            sleep 5
            exit 1
        fi
    fi
fi

for i in $(members -p $GRUPPO_PRIMARIO)
do
    # Lettura dati (sempre eseguita, non modifica nulla)
    home=$(smbldap-usershow "$i" | awk '/^homeDirectory/ {print $2}')
    if [ -z "$home" ]; then continue; fi

    home_tr=${home%"/$i"}  
    home_mod=${classi[$home_tr]}

    if [ -z "$home_mod" ]; then
        echo "⚠️ Nessuna corrispondenza trovata per $home_tr — skip utente $i"
        continue
    fi

    echo "Elaborazione utente: $i ($home -> $home_mod/$i)"

    # Modifiche protette da run
    run smbldap-usermod -d "$home_mod/$i" "$i"
    run mv "$home" "$home_mod/$i"

    if [ -e group_mapping.csv ]; then
        # 1. Recuperiamo i gruppi dell'utente UNA SOLA VOLTA per questo utente
        # Usiamo una variabile per "congelare" la situazione dei gruppi a questo istante
        USER_GROUPS_SNAPSHOT=$(id -nG "$i")

        for oldgroup in "${!gruppi[@]}"; do
            # 2. Controlliamo nella foto dei gruppi scattata prima, non nel sistema "live"
            if echo "$USER_GROUPS_SNAPSHOT" | grep -qw "$oldgroup"; then
                newgroup=${gruppi[$oldgroup]}
                echo "   🔄 Gruppo: $oldgroup → $newgroup"
                
                run smbldap-groupmod -x "$i" "$oldgroup"
                run smbldap-groupmod -m "$i" "$newgroup"
                
                # 3. IMPORTANTE: Una volta trovato e spostato il gruppo classe, 
                # non dobbiamo cercarne altri per questo utente.
                break 
            fi
        done
    fi
done

echo "Spostamento cartelle comuni..."
while IFS=, read -r OLDHOME NEWHOME
do
    OLDHOME=$(echo "$OLDHOME" | tr -d '\r' | xargs)
    NEWHOME=$(echo "$NEWHOME" | tr -d '\r' | xargs)
    
    if [ -n "$CARTELLA_COMUNE" ] && [ -d "$OLDHOME/$CARTELLA_COMUNE" ]; then
        if [ ! -d "$NEWHOME/$CARTELLA_COMUNE" ]; then
            # Recupero info (lettura)
            OLD_GRUPPO_COMUNE=$(stat -c "%G" "$OLDHOME/$CARTELLA_COMUNE" 2>/dev/null)
            NEW_GRUPPO_COMUNE=${gruppi[$OLD_GRUPPO_COMUNE]}
            
            run mv "$OLDHOME/$CARTELLA_COMUNE" "$NEWHOME/"
            
            if [ -n "$NEW_GRUPPO_COMUNE" ]; then
                run chgrp -R "$NEW_GRUPPO_COMUNE" "$NEWHOME/$CARTELLA_COMUNE"
            else
                echo " ⚠️ Nessuna corrispondenza per gruppo $OLD_GRUPPO_COMUNE"
            fi
        fi
    fi
done < classes_mapping.csv

echo "Pulizia directory vecchie..."
for oldhome in "${!classi[@]}"; do
    run rmdir "$oldhome"
done

echo " Operazione completata."
