# env/bin/bash sh

# Ce programme a pour but d'automatiser l'ajout de colonne dans la table Graph_viaire_ville_information de l'application recuperateur_reseau_viaire
# Nous allons nous baser sur la doc https://docs.djangoproject.com/fr/4.1/topics/migrations/

# constantes erreurs retours de fonctions
EXIT_SUCCESS=0
EXIT_ERROR=1

function modifie_methode_migration_modification_utilisation_fonction_OSMnx_recuperation_graph_information() {
    #Cette fonction a pour but qu'un fois la méthode de récupération de fichier faire le fichier de migration utilise la
    #méthode provenant de la classe OSMnx_recuperation_graph_information. Cela va nous permettre de réutiliser le
    #fichier de migration en cas de réutilisation lors par example.
    #elle prends en paramètre le nom de la nouvelle variable et le nom de la fonction de récupération de fonction
    nom_variable=$1
    nom_fonction=$2

    #le chemin vers le dossier des migrations de l'application recuperateur_reseau_viaire
    chemin_vers_migration=./../recuperateur_reseau_viaire/migrations/
    #le chemin du fichier tampon à remplir au fur et à mesure
    chemin_vers_cible=./../recuperateur_reseau_viaire/migrations/_migration_tampon
    #récupère le fichier migration contenant le mot _auto_ et ayant le numéro le plus élevé en début de nom (le plus récent)
    dernier_fichier_migration=$(ls -v -r -1 ${chemin_vers_migration}| grep '_auto_' | head -1)
    #concatène le chemin vers le dossier des migrations et le nom de fichier le plus récent
    chemin_dernier_fichier_migration=${chemin_vers_migration}${dernier_fichier_migration}

    cat $chemin_dernier_fichier_migration | grep -v 'np.load' | grep -v 'numpy' | sed -n '0, /all()/p' > $chemin_vers_cible
    echo -e "        G = OSMnx_recuperation_graph_information.lire_graphe(graph.gvvi_nom)" >> $chemin_vers_cible
    echo -e "        graph.$nom_variable = OSMnx_recuperation_graph_information.$nom_fonction(G)[\"$nom_variable\"]" >> $chemin_vers_cible
    cat $chemin_dernier_fichier_migration | sed -n '/save/, $p' >> $chemin_vers_cible
    cat $chemin_vers_cible > $chemin_dernier_fichier_migration
    rm $chemin_vers_cible
}

function modifie_model()
{
  #cette fonction permet de modifier le fichier model de l'application recuperateur_reseau_viaire
  # elle reçoit en paramètre le type et le nom de la nouvelle variable à rajouter dans le model
  type=$1
  nomvariable=$2
  #le chemin du fichier tampon à remplir au fur et à mesure
  chemin_cible=./../recuperateur_reseau_viaire/_models
  #le chemin vers le model de l'application recuperateur_reseau_viaire
  chemin_vers_model=./../recuperateur_reseau_viaire/models.py

  #permet de récupérer le numéro de la ligne du début de la classe Model
  ligne_debut_classe=$(grep -n 'class Graph' $chemin_vers_model)
  ligne_debut_classe=$(echo $ligne_debut_classe | cut -d ':' -f 1)

  #affiche le texte jusqu'au début de la classe dans un nouveau fichier
  awk "NR<=$ligne_debut_classe{print \$0}" < $chemin_vers_model > $chemin_cible

  #ajoute au début de la classe la nouvelle variable
  echo -e "\t$nomvariable = models.$type()" | expand -t 4 >> $chemin_cible

  #affiche le reste du fichier
  ligne_debut_classe=$((ligne_debut_classe + 1))
  awk "NR>=$ligne_debut_classe{print \$0}" $chemin_vers_model >> $chemin_cible

  #réécris le fichier model d'origine avec le nouveau fichier puis supprime le fichier tampon
  cat $chemin_cible > $chemin_vers_model
  rm $chemin_cible
}


function modifie_methode_migration_vide()
{
  #cette fonction permet de modifier le nouveau fichier de migration de donnée en lui ajoutant le lien vers la nouvelle
  #fonction de remplissage de la base de donnée. Cette migration de donnée pourra alors permettre de remplir la nouvelle
  #colonne des données anciennes
  #elle prends en paramètre le nom de la nouvelle variable et le nom de la fonction de récupération de fonction
  nom_variable=$1
  nom_fichier_retour_methode=$2

  #le chemin vers le dossier des migrations de l'application recuperateur_reseau_viaire
  chemin_vers_migration=./../recuperateur_reseau_viaire/migrations/
  #le chemin du fichier tampon à remplir au fur et à mesure
  chemin_vers_cible=./../recuperateur_reseau_viaire/migrations/_migration_tampon
  #récupère le fichier migration contenant le mot _auto_ et ayant le numéro le plus élevé en début de nom (le plus récent)
  dernier_fichier_migration=$(ls -v -r -1 ${chemin_vers_migration}| grep '_auto_' | head -1)
  #concatène le chemin vers le dossier des migrations et le nom de fichier le plus récent
  chemin_dernier_fichier_migration=${chemin_vers_migration}${dernier_fichier_migration}
  #chemin vers le fichier model de méthode nécessaire pour ajouter des données dans les lignes de la table existant
  chemin_fichier_fonction_ajout_model=./migration_fichier_model
  #permet de récupérer le numéro de la ligne du début de la classe Migration
  ligne_debut_classe=$(grep -n 'class Migration' $chemin_dernier_fichier_migration)
  ligne_debut_classe=$(echo $ligne_debut_classe | cut -d ':' -f 1)

  #affiche les lignes du fichier jusqu'à la ligne de début de classe exclue
  awk "NR<$ligne_debut_classe{print \$0}" $chemin_dernier_fichier_migration > $chemin_vers_cible
  #ajoute un fichier de méthode model à toutes les migrations en remplaçant les cases tel que :
  # le nouveau nom de la variable
  # le nom dee la méthode de récolte de donnée OSMnx_recuperation_graph_information
  cat $chemin_fichier_fonction_ajout_model | sed -s "s/&&nom_variable&&/$nom_variable/g" | sed -s "s+&&nom_fichier_retour&&+$nom_fichier_retour_methode+g" >> $chemin_vers_cible
  #récupère le numéro de ligne dans le fichier pour ajouter un appelle de méthode à l'avant dernière ligne
  echo -e "\n" >> $chemin_vers_cible
  nb_ligne_model=$(cat $chemin_dernier_fichier_migration | wc -l)
  #afiche toute la classe de migration excepté la dernière ligne
  awk "($ligne_debut_classe <= NR && NR < $nb_ligne_model){print \$0}" $chemin_dernier_fichier_migration >> $chemin_vers_cible

  #ajout de l'appel de fonction
  echo -e "\t\tmigrations.RunPython(ajoute_donnees_nouvelle_colonne)" | expand -t 4 >> $chemin_vers_cible
  echo -e "\t]" | expand -t 4 >> $chemin_vers_cible

  #réécris le fichier Migration d'origine avec le nouveau fichier puis supprime le fichier tampon
  cat $chemin_vers_cible > $chemin_dernier_fichier_migration
  rm $chemin_vers_cible
}

function modifie_template_index()
{
  # Cette fonction permet de modifier le fichier index du template de l'application recuperateur_reseau_viaire
  # cette modification correspond à l'ajout d'une nouvelle colonne dans la table d'affichage de notre base de donnée
  # ele prend en paramètre le nom de la nouvelle variable
  nomvariable=$1

  #chemin vers le fichier index de l'application recuperateur_reseau_viaire
  chemin_vers_template_index=./../recuperateur_reseau_viaire/templates/recuperateur_reseau_viaire/index.html
  #chemin vers fichier_tampon à remplir au fur et à mesure
  chemin_vers_index_tampon=./../recuperateur_reseau_viaire/templates/recuperateur_reseau_viaire/_index.html
  #donne le numéro de la ligne dans le fichier de la fermeture de la première ligne de tableau
  ligne_tr_premier_tr=$(cat $chemin_vers_template_index | sed -n '1,  /<\/tr>/p' | wc -l)

  #affichage du fichier du début à la ligne de la première fermeture de tr exclue
  awk "NR < $ligne_tr_premier_tr {print \$0}" $chemin_vers_template_index > $chemin_vers_index_tampon

  #ajout du nom de notre variable
  echo -e "\t<th>$nomvariable</th>" | expand -t 4 >> $chemin_vers_index_tampon

  #donne le numéro de la ligne dans le fichier de la fermeture de la case de ligne avant le premier lien
  ligne_avant_premier_lien=$(cat $chemin_vers_template_index | sed -n '1,  /<a /p' | wc -l)
  ligne_avant_premier_lien=$((ligne_avant_premier_lien - 1))
  #affichage du reste du fichier jusqu'a la dernière case du premier tableau
  awk "($ligne_tr_premier_tr <= NR && NR < $ligne_avant_premier_lien){print \$0}" $chemin_vers_template_index >> $chemin_vers_index_tampon
  #ajout de notre case
  echo -e "\t\t<td>{{ graph.$nomvariable }}</td>" | expand -t 4 >> $chemin_vers_index_tampon

  #ajout début case des liens
  echo -e "\t\t<td>" | expand -t 4 >> $chemin_vers_index_tampon
  #affichage du reste du fichier
  cat $chemin_vers_template_index | sed -n '/<a /, $ p' >> $chemin_vers_index_tampon

  cat $chemin_vers_index_tampon > $chemin_vers_template_index
  rm $chemin_vers_index_tampon

}


function test_fichier_test_associe_a_migration()
{
  # Cette fonction permet d'utiliser le fichier test associé à la migration de donnée
  # si tous les testes ne passent pas on retourne une erreur
  # Elle prend en paramètre le nom du fichier test
  nom_fichier_test=$1

  python ./../manage.py test OSM_outils.Tests."$nom_fichier_test"
  retour=$?
  if [[ $retour -eq 0 ]]
  then
    return $EXIT_SUCCESS
  else
    return $EXIT_ERROR
  fi
}

function main(){
  #Cette fonction a pour but de lancer toutes les fonctions dans le bonne ordre pour
  #faire une migration de schéma et une migration de donnée.
  # Elle a aussi pour but de modifier les fichiers du projets pour ajuster le projet à la nouvelle colonne
  # tel que :
  # - le model
  # - la méthode de migration de donnée dans le fichier plus-haut-nombre_auto_une-date_un-nombre.py
  # - le template index.html
  echo "pour faire tourner ce programme le terminal doit être dans utiliser le venv"
  read -p "continuer ? y ou n " continuer
  if [ $continuer == "y" ] || [ $continuer == "Y" ]
  then
    #chemin vers le fichier de sauvegarde
    fichier_decision_utilisateur_ajout_colonne=./sauvegarde_var
    #lecture des variables depuis le fichier
    valeurs=$(cat $fichier_decision_utilisateur_ajout_colonne | awk '{print $2 "  " $3}')
    nomvariable=$(echo $valeurs | cut -d ' ' -f 1)
    type_variable=$(echo $valeurs | cut -d ' ' -f 2)
    nom_fonction=$(echo $valeurs | cut -d ' ' -f 3)
    nom_fichier_test=$(echo $valeurs | cut -d ' ' -f 4)
    #le nom du fichier dans lequelle nous allons écrire le retour de la nouvelle fonction de récupération de
    # données du graphe dans OSMnx_recuperation_graph_information
    nom_fichier_retour_methode=./retour_method.npy
    # Test de la nouvelle méthode de récupération de données, si la méthode ne renvoie pas une liste de valeur,
    # on fait pas la migration, sinon on arrête le script ici
    test_fichier_test_associe_a_migration $nom_fichier_test
    retour=$?
    if [ $retour -ne $EXIT_SUCCESS ]
    then
       echo "tous les tests du fichier test $nom_fichier_test ne sont pas passé"
       exit
    fi

    modifie_model  $type_variable $nomvariable

    python ../manage.py makemigrations recuperateur_reseau_viaire

    python ../manage.py makemigrations --empty recuperateur_reseau_viaire

    modifie_methode_migration_vide $nomvariable $nom_fichier_retour_methode

    python ../manage.py migrate

    modifie_template_index $nomvariable

    modifie_methode_migration_modification_utilisation_fonction_OSMnx_recuperation_graph_information $nom_variable $nom_fonction
  fi
}

main
