##==============================================================================================
##                                                                                            ##
##                                  Script gitea-restore.sh                                   ##
##                                                                                            ##
##==============================================================================================
##                                                                                            ##
## gitea-restore.sh <méthode de backup> <fichier à restaurer>                                 ##
##        <méthode de backup>   = --gitea_dump       ou   --gdmp                              ##
##                              = --archive_dossier  ou   --ad                                ##
##        <fichier à restaurer> = le nom du fichier archive à utiliser pour la restauration.  ##
##                                Ne peut être qu'un .zip pour la méthode --gitea_dump,       ##
##                                ou bien                                                     ##
##                                ne peut être qu'un .tar.gz pour la méthode --archive_dossier #
##        Il faut impérativement donner le chemin d'accès complet de ce fichier archive...    ##
##                                                                                            ##
##==============================================================================================

##==============================================================================================
##                                                                                            ##
## Objectif du script : Restaurer la sauvegarde de Gitea passée en paramètre                  ##
## Il faudra indiquer la méthode de restauration basée sur le type de sauvegarde à restaurer. ##
## Il faudra également indiquer l'archive à utiliser pour la restauration.                    ##
##                                                                                            ##
##==============================================================================================
##                                                                                            ##
##      Une méthode officielle de restauration, de la base de données est présente ici :      ##
##           https://docs.gitea.io/en-us/backup-and-restore/#restore-command-restore          ##
##                                                                                            ##
##==============================================================================================

##==============================================================================================
##                                                                                            ##
## MAJ du 19.04.2021 : La partie de sauvegarde gite_dump ne sera pas programmée car c'est     ##
## trop galère à mettre en place.                                                             ##
## Donc soit on ne donne aucun paramètre en argument au script, soit on met archive_dossier.  ##
## L'autre paramètre n'aura donc plus aucun effet. Ne pas l'utiliser !                        ##
## Cependant le code pour distinguer les deux paramètres reste, mais il n'y aura rien dans    ##
## la partie gitea_dump.                                                                      ##
##                                                                                            ##
##==============================================================================================


# Récupération des arguments qu'on place dans des variables constantes
declare -r nb_arg=$#            # Nombre d'argument(s) fourni(s) au script.
declare -r methode="$1"         # 1er argument fourni
declare -r fichier="$2"         # 2ème argument fourni
declare -r tous_les_args="$*"  # Tous les arguments

##==============================================================================================
##                                   VALEURS À PERSONNALISER                                  ##
##                                                                                            ##
##       Chemin d'accès vers votre dossier docker et vers le dossier de backup de gitea       ##
##==============================================================================================
# Chemin complet du dossier qui contient le dossier des données (data) et des backups (backup-data)
GITEA_DOCKER_DIR=/volume1/docker/gitea

# Les noms des dossiers montés dans le conteneur doivent êtres identiques à ceux présents sur la machine hôte. Sinon faudra modifier le script...
# Nom du dossier contenant les backups qui doit exister car il doit être monté dans le conteneur à l'aide du docker-compose.yml.
GITEA_BACKUP_DIR=backup-data

# Nom du dossier contenant les donneés de Gitea (data) 
GITEA_DATA_DIR=data

# Nom du conteneur
NOM_CONTENEUR=gitea

# ID de l'utilisateur du NAS qui a les droits sur le conteneur
ID_USER_NAS=1000
##==============================================================================================
##==============================================================================================

echo 
echo "Le script gitea-restore.sh permet de faire une restauration des données du conteneur Gitea."
echo

##────  ────────────────────────────────────────────────────────────────────────────────────────
##                        Début de la section concernant les fonctions                        ##
##────  ────────────────────────────────────────────────────────────────────────────────────────

f_affiche_syntaxe(){
  # Fonction pour afficher la syntaxe d'utilisation du fichier script.
  # syntax: f_affiche_syntaxe <paramètre1> [<paramètre2>]
  # 1er paramètre : $1
  # 2nd paramètre éventuel : $2   Ce sera ce qui a été fourni en argument du script.
  local f_nb_arg=$#
  local f_param_1=$1
  local f_param_2=$2  
  echo
  if [ "$f_param_1" = "#1" ]; then
      echo "La méthode de restauration choisie '$f_param_2' est incorrecte."
      echo
  elif [ "$f_param_1" = "#2" ]; then
    if [ -z "$f_param_2" ]; then
      echo "Aucun paramètre n'a été fourni au script..."
    else
      echo "Le nombre de paramètre fourni n'est pas correct.    Paramètres fournis : '$f_param_2'"
    fi
    echo
  fi
  echo "Utilisation : gitea-restore.sh <méthode de backup> <fichier à restaurer>"
  #echo " * <méthode de backup> : --gitea_dump       ou   --gdmp   pour utiliser la méthode gitea dump."
  
  echo " * <méthode de backup> :   --archive_dossier  ou   --ad     pour utiliser la méthode archive dossier."
  echo " * <fichier à restaurer> : le nom du fichier archive à utiliser pour la restauration."
  #echo "                          Ne peut être qu'un .zip pour la méthode --gitea_dump,"
  #echo "                          ou bien ne peut être qu'un .7z ou .tar.gz pour la méthode --archive_dossier"
  echo "                          Ne peut être qu'un .7z ou un .tar.gz pour la méthode --archive_dossier."
  echo "                          Il faut impérativement donner le chemin d'accès complet de ce fichier archive..."
  echo
  
  if [ "$f_param_1" = "#3" ]; then
    exit 1
  fi
  exit 3
}

f_verif_fichier_existe() {
  # Fonction qui vérifie si le fichier fourni en paramètre existe, et qu'il s'agit d'un
  # fichier zip ou d'un fichier 7z.
  # Quoiqu'il arrive, l'appel à cette fonction marque la fin du script.
  #
  # syntax: f_verif_fichier_existe [<fichier_a_tester>]

  local fichier_a_tester=$1

  if [ -z "$fichier_a_tester" ]; then
    echo "!! Erreur fatale, le paramètre à tester de la fonction f_verif_fichier_existe() est vide ! Revoir l'appel à la fonction..."
    echo "!! Fin du script. Code d'erreur 10."
    return 11 # On stoppe immédiatement l'exécution de la fonction !
  fi
  if [ ! -s "$fichier_a_tester" ]; then        # Le fichier 'fichier_a_tester' n'existe pas ou a un taille de 0 !
    return 1    # C'est le code d'erreur pour indiquer que le fichier n'existe pas.
  fi

  # Quelle est l'extension du fichier fichier_a_tester ?
  fullfilename="$fichier_a_tester"
  filename=$(basename "$fullfilename")
  ext="${filename#*.}"
  echo $ext
  return 0
}

f_verif_dossier_existe() {
  # Fonction qui vérifie si le dossier fourni en paramètre existe.
  #
  # syntax: f_verif_dossier_existe <dossier_a_tester>

  local dossier_a_tester=$1   # On récupère le 1er paramètre passé en argument à la fonction.

  if [ -d "$dossier_a_tester" ]; then        # Le dossier 'dossier_a_tester' existe ! Il sera renommé.
    return 0    # C'est le code d'erreur pour indiquer que le dossier existe bien.
  else
    return 1    # C'est le code d'erreur pour indiquer que le dossier n'existe pas.
  fi

  # Si le script arrive ici, c'est qu'il y a un soucis...
  echo "BLABLA Si tu lis ça, c'est que y a une couille dans le paté !!! 9988"
  exit 9988
}
##────  ────────────────────────────────────────────────────────────────────────────────────────
##                         Fin de la section concernant les fonctions                         ##
##────  ────────────────────────────────────────────────────────────────────────────────────────


##────  ────────────────────────────────────────────────────────────────────────────────────────
##                                Début du programme principal                                ##
##────  ────────────────────────────────────────────────────────────────────────────────────────
if [ $nb_arg -ne 2 ]; then
  f_affiche_syntaxe "#2" "$tous_les_args"     # On affiche la syntaxe car le nombre de paramètres n'est pas correct.
fi

mode_backup=""
case "$methode" in
  --[hH][eE][lL][pP] | --[hH] | -[hH][eE][lL][pP] | -[hH] )         # Premier argument --help ou --h
    f_affiche_syntaxe        # On affiche la syntaxe
    ;;

  --gitea_dump | --gdmp)
    mode_backup="gitea_dump"
    ;;      # On ne surcharge pas cette partie avec le code de restauration, ce sera fait plus bas.

  --archive_dossier | --ad)
    mode_backup="archive_dossier"
    ;;      # On ne surcharge pas cette partie avec le code de restauration, ce sera fait plus bas.

  *)        # Aucune méthode sélectionnée valide ou bien trop d'arguments
    mode_backup="non_choisi"
    f_affiche_syntaxe "#1" "$methode"     # On affiche la syntaxe car le paramètre de méthode est incorrect.
    echo "BLABLA Si tu lis ça, c'est que y a une couille dans le paté !!! 9999"
    exit 9999
    ;;
esac

echo "La méthode de restauration choisie est : $methode "
echo

# Test si le fichier en argument existe et est valide (archive zip pour ).
ext_fichier=""
ext_fichier="$(f_verif_fichier_existe $fichier)"      # Vérification que le fichier à restaurer existe bien et est bien un .zip ou un .7z
retour_fct=$?     # Le code d'exit de la fonction est stocké dans cette variable.
if [ $retour_fct -ne 0 ]; then
  case "$retour_fct" in
    1)    # Le fichier n'existe pas.
      echo "!! Le fichier $fichier n'existe pas. La restauration ne peut pas s'effectuer."
      echo "!! Fin du script. Erreur 10"
      echo
      exit 10
      ;;
    11)   # Problème avec l'appelle de la fonction, revoir le code ci-dessus...
      exit 11
      ;;
  *)      # Toutes autres valeurs ne devrait pas exister !
    echo "!! Erreur fatale qui ne devrait pas exister !"
    echo "!! Code d'erreur 1000"
    exit 1000
    ;;
  esac
else
  echo "Le fichier existe et a une taille non nulle. Le script peut continuer."
  echo
  echo "Début de la restauration ---"
fi

cd $GITEA_DOCKER_DIR    # On se place dans le dossier du conteneur gitea
retour_cmd=$?     # Le code d'exit de la fonction est stocké dans cette variable.
if [ $retour_cmd -ne 0 ]; then
  echo "!! Le dossier $GITEA_DOCKER_DIR semble ne pas exister. Vérifier la variable GITEA_DOCKER_DIR dans le script."
  echo "!! Fin du script. Erreur 333"
  echo
  exit 333
fi

# Note :  Si le dossier GITEA_DATA_DIR existe il sera renommé en GITEA_DATA_DIR--$(date +%Y-%m-%d--%Hh%M)
#         avec la commande mv "$GITEA_DATA_DIR" "$GITEA_DATA_DIR--$(date +%Y-%m-%d--%Hh%M)"
#         Ce test sera fait lors de l'appel de la fonction verif_dossier_existe().
#         Aucun choix ne sera possible, le dossier existant sera forcément renommé.
#
# Note :  Il faut que le dossier GITEA_BACKUP_DIR existe, ce qui semble acquis vu que le fichier backup
#         à restaurer doit être dedans... Mais il est vital que ce dossier existe car un dossier 'TEMP'
#         y sera créé pour extraire les données de l'archive (zip, 7z, ou tar.gz)...
#
# On teste maintenant l'existence des deux dossiers précédents.
# Si un des deux dossiers n'est pas présents, le script sera interrompu.

# 1er test : GITEA_DATA_DIR
retour_fct=11111  # Valeur reset.
f_verif_dossier_existe $GITEA_DATA_DIR
retour_fct=$?     # Le code d'exit de la fonction est stocké dans cette variable.
if [ $retour_fct -eq 0 ]; then  # Le dossier existe, on peut continuer
  echo "-- Le dossier $dossier_a_tester existe et va être renommé en $dossier_a_tester--$(date +%Y-%m-%d--%Hh%M)"
else  # Le dossier n'existe pas
  echo "!! Le dossier $dossier_a_tester n'existe ! Veuillez créer le dossier $dossier_a_tester puis relancer le script."
  echo "!! Interruption de l'exécution du script. Code 444"
  exit 444    # C'est le code d'erreur pour indiquer que le dossier n'existe pas et que le script a été interrompu.
fi

# 2ème test : GITEA_BACKUP_DIR
retour_fct=11111  # Valeur reset.
f_verif_dossier_existe $GITEA_BACKUP_DIR
retour_fct=$?     # Le code d'exit de la fonction est stocké dans cette variable.
if [ $retour_fct -eq 0 ]; then  # Le dossier existe, on peut continuer
  echo "-- Le dossier $dossier_a_tester existe bien. La restauration peut continuer."
else  # Le dossier n'existe pas
  echo "!! Le dossier $dossier_a_tester n'existe ! Vérifier que ce dossier est bien paramétré dans le script."
  echo "!! Interruption de l'exécution du script. Code 555"
  exit 555    # C'est le code d'erreur pour indiquer que le dossier n'existe pas et que le script a été interrompu.
fi

# Maintenant on sait que les deux dossiers GITEA_BACKUP_DIR et GITEA_DATA_DIR existent.

case "$mode_backup" in
  gitea_dump)
    
    if [ $ext_fichier != "zip" ]; then
      echo "!! Le fichier archive $(basename "$fichier") n'est pas une archive ZIP."
      echo "!! Fin du script."
      f_affiche_syntaxe "#3"
    fi

    echo -e "\t-- Méthode de restauration à venir, un jour si j'ai le courage...\n"
    echo -e "\t-- Donc, pour le moment il ne se passera rien avec cette méthode...\n"
    exit 0

    # Extraction de l'archive zip créé avec gitea dump avec 7z :
    # 7z x -o/volume1/docker/gitea/backup-data -tzip /volume1/docker/gitea/backup-data/gitea-dump-1618217429.zip

    echo
    ;;
  
  archive_dossier)
    
    if [ $ext_fichier != "7z" ] && [ $ext_fichier != "tar.gz" ]; then
      echo "!! Le fichier archive $(basename "$fichier") n'est pas une archive 7z ou tar.gz."
      echo "!! Fin du script."
      f_affiche_syntaxe "#3"    # Le script est interrompu.
    fi
    
    echo -e "\t-- Restauration de la sauvegarde $fichier \n\t   par extraction de  l'archive dans le dossier $GITEA_DATA_DIR\n"
   
    # Comme on sait que le dossier existe, il est renommée après avoir éteint le conteneur.
    retour_cmd=1111 # Valeur reset
    echo -e "\t-- Extinction du conteneur $(docker stop $NOM_CONTENEUR)\n"
    retour_cmd=$?     # Le code d'exit de la fonction est stocké dans cette variable.
    if [ $retour_cmd -ne 0 ]; then
      if [ $retour_cmd -eq 1111 ]; then
        echo "### DEBUG : soucis avec la récupération du retour de commande #1470000 "
        exit 1470000
      fi
      echo "!! Le conteneur $NOM_CONTENEUR ne peut pas être arrêté..."
      echo "!! Fin du script. Erreur 777"
      echo
      exit 777
    fi
    
    mv "$GITEA_DATA_DIR" "$GITEA_DATA_DIR--$(date +%Y-%m-%d--%Hh%M)"

    # En fonction du type d'archive donnée en paramètre au script, ce n'est pas la même manière d'extraire les données.
    # Mais quoiqu'il arrive on crée un dossier TEMP dans le dossier GITEA_BACKUP_DIR pour y placer les données extraites.
    # Ce dossier TEMP sera supprimé à la fin de la restauration.
    mkdir "$GITEA_BACKUP_DIR/TEMP"

    case "$ext_fichier" in
      7z)
        echo -e "\t-- Extraction des données de l'archive 7z utilisée.\n"
        # Restauration d'un fichier 7z :
        7z x -so $fichier | tar xf - -C "$GITEA_BACKUP_DIR/TEMP"
        ;;
      tar.gz)
        echo -e "\t-- Extraction des données de l'archive tar.gz utilisée.\n"
        # Restauration d'un fichier tar.gz :
        tar -xzf $fichier -C "$GITEA_BACKUP_DIR/TEMP"
        ;;
      *)
        echo "Erreur d'extension non prévue ! Revoir le code. Erreur 88."
        exit 88
    esac
    
    # On déplace le dossier extrait data dans GITEA_DOCKER_DIR (Rappel on est dans le dossier gitea qui contient le dossiers GITEA_BACKUP_DIR)
    mv "$GITEA_BACKUP_DIR/TEMP/data" "$GITEA_DOCKER_DIR"    # On pourrait utiliser "./" à la place de "$GITEA_DOCKER_DIR"

    # Le dossier TEMP étant maintenant vide, on le supprime
    rm -rf "$GITEA_BACKUP_DIR/TEMP"
    
    retour_cmd=1111 # Valeur reset
    echo -e "\t-- Redémarrage du conteneur $(docker start $NOM_CONTENEUR)\n"
    retour_cmd=$?     # Le code d'exit de la fonction est stocké dans cette variable.
    if [ $retour_cmd -ne 0 ]; then
      if [ $retour_cmd -eq 1111 ]; then
        echo "### DEBUG : soucis avec la récupération du retour de commande #1470000 "
        exit 1470000
      fi
      echo "!! Le conteneur $NOM_CONTENEUR ne peut pas être redémarré..."
      echo "!! Fin du script. Erreur 777"
      echo
      exit 777
    fi
    ;;

  *)
    echo "!! Un problème est survenu ! Revoir le script. Code XYZ = 199 !"
    echo
    return 199
    ;;
esac

echo
echo "Restauration terminée. Bonne journée :)"
echo