#!/bin/bash

# Cette méthode a pour but de connaitre le nombre de rues ayant un attribut associé tel que la largeur de la rue,
# le nombre de voies ... Nous allons grouper les arrêtes (edges) en fonction de leurs osmid et de leurs nom de rue
# pour connaitre la présence ou nom d'attributs recherché et dans qu'elle proportion
#
# Ce script prend en argument :
# - Le chemin jusqu'au fichier graphml
# - une suite de nom d'attributs recherché
#
# example :
# ./nb_rues_avec_attr.sh ./../Data/Bolbec.graphml width lanes maxspeed length
# ici nous allons analyser dans le fichier représentatif de la ville de Bolbec la présence des attributs :
# - width
# - lanes
# - maxspeed
# - length
#
# Le résultat escompté est un fichier nommé "sortie" comprenant une suite de rues suivie de ---- si nous avons trouvé
# nos attributs ou de #### dans le cas contraire
# Si nous avons trouvé des paramètres nous ajoutons à la suite les codes des attributs trouvé
#
# example :
# rue des indispensables############################
# rue de Paris--------------------
# d13
# d16
#
# Ici nous n'avons trouvé aucun de nos attributs dans la rue des indipensables mais nous avons trouvé les attributs d13
# et d16 dans la rue de Paris


function get_key_id() {
  #cette méthode permet de retourner l'identifiant associé au nom d'attribut entré en paramètre dans le fichier également entré en paramètre
  #paramètres : clef $1 le nom de l'attribut
  #paramètres : chemin_vers_fichier $2 le chemin vers le fichier graphml
  #
  # retour : nombre de la clef de l'attribut
  #
  # example :
  # <key id="d16" for="edge" attr.name="maxspeed" attr.type="string" />
  # ici le nom de l'atribut est maxspeed et nous retournons 16
  clef=$1
  chemin_vers_fichier=$2
  return "$(cat "$chemin_vers_fichier" | grep "name=\"$clef" | grep -o 'id="[^ ]*' | grep -o '[0-9]*' | head -n 1)"
}


function recupere_info() {
  # Cette fonction permet d'écrire dans le fichier sortie les noms de rues qui possèdent les clef recherché.
  # Elle prend en paramètre une liste de nom de rues, les noms de rues doivent remplcer leurs espaces par des _ pour ne
  # pas splitter les noms en plusieurs chaines de caractères
  # example :
  # Nom de rue--------------------
  # d12
  # d23
  # ici la rue "nom de rue" possède les informations d12 et d23
  local liste_nom=("$@")
  local nb_rue_traitees=0
  local total_nb_rues_local=${#liste_nom[@]}
  echo "local taille tab nom_rues : $total_nb_rues_local"

  for nom_rue in "${liste_nom[@]}"
  do
      # les nom de rues sont composé d'espaces
      nom_rue=$(echo "$nom_rue" | tr '_' ' ')
      #on récupère les clef osmid associé à chaque arrêtes ayant un attribut nom
      osm_id_liste=$(echo "$bloques_edges" | grep "$nom_rue" | grep -o "<data key=\"d$key_id_osm_id\">[^<]*" | cut -d '>' -f 2 | cut -d '<' -f 1 | sed -s 's/\[\|\]//g' | sed -s 's/, /\n/g' | sort --uniq)
      #on récupère les noms de rues qui se partagent la même arrêtes mais qui ne sont pas la rue actuellement traité ($nom_rue)
      #nom_intrus=$(echo "$bloques_edges" | grep "$osm_id_liste"  | grep -o "d$key_name\">[^<]*" | grep "\[[\"-']" | sed -s "s/d$key_name\">//g" | sed -s "s/[\"-'], [\"-']/\n/g" | grep -v "$nom_rue" | sed -s "s/\[[\"-']//g ; s/[\"-']\]//g")
      noms_des_intrus=$(echo "$bloques_edges" | grep "$osm_id_liste"  | grep -o "d$key_name\">[^<]*" | grep "\[[\"-']" | sed -s "s/d$key_name\">//g" | sed -s "s/[\"-'], [\"-']/\n/g" | grep -v "$nom_rue" | sed -s "s/\[[\"-']//g ; s/[\"-']\]//g" | sort --uniq | sed -s "s/^/>/g ; s/$/</g")

      if [[ -n $nom_des_intrus ]]
      then
        osm_id_liste_intrus=$(echo "$bloques_edges" | grep "$osm_id_liste" | grep "$noms_des_intrus" | grep -o "<data key=\"d$key_id_osm_id\">[^<]*" | cut -d '>' -f 2 | cut -d '<' -f 1 | sed -s 's/\[\|\]//g' | sed -s 's/, /\n/g' | sort --uniq)
        osm_id_liste=$(echo "$osm_id_liste" | grep -v "$osm_id_liste_intrus")
      fi
      resultat=$(echo "$bloques_edges" | grep "$osm_id_liste" | grep -o "$grep_expression_variable_a_garder" | sort --uniq)

      #on compte le nombre de rue traité
      let "nb_rue_traitees = nb_rue_traitees + 1"
      #on affiche les résultats en fonction de la présence ou nom d'attributs recherché
      if [ -n "$resultat" ]
      then
        echo "$nom_rue-----------------------------------------------" >> sortie
        echo "$( echo "$resultat" | cut -d '>' -f 1 | cut -d '"' -f 2 | sort --uniq)" >> sortie
        echo "$nb_rue_traitees sur $total_nb_rues_local"
      else
        echo "$nom_rue#################################################" >> sortie
      fi
  done
}

#récupération des clefs importantes du fichier : les arguments du script et la clef osmid et name associé aux edges du fichier
chemin_vers_fichier=$1
shift
grep_expression_variable_a_garder=""
i=0
declare -A tab_identifiant_osm_a_garder
#faire en sorte qu'on affiche dans sortie toutes les clef disponibles dans une rue
for var in "$@"
do
    get_key_id "$var" "$chemin_vers_fichier"
    clef=$?
    echo "$var : $clef"
    tab_identifiant_osm_a_garder[$var]="d$clef"
    if [ $i == 1 ]
    then
      grep_expression_variable_a_garder=$grep_expression_variable_a_garder"\|<data key=\"d$clef\">[^ ]*"
    else
      grep_expression_variable_a_garder=$grep_expression_variable_a_garder"<data key=\"d$clef\">[^ ]*"
    fi
    i=1
done
get_key_id osmid "$chemin_vers_fichier"
key_id_osm_id=$?
get_key_id name "$chemin_vers_fichier"
key_name=$?

echo "key_osm_id : $key_id_osm_id"
echo "key_name : $key_name"
# récupération de la liste des noms de rues, les espaces sont remplacés par des "_" pour ne pas être coupé dans un
# passage dans une boucle for
list_rues_noms=$(cat "$chemin_vers_fichier"  | grep "key=\"d$key_name\">" | cut -d '>' -f 2 | cut -d '<' -f 1 | sed -s "s/[\"-'], [\"-']/\n/g" | sed -s "s/\[[\"-']//g ; s/[\"-']\]//g"  | sort --uniq | tr ' ' '_')

# On récupére tous les informations concernant les arrêtes du fichier afin de l'alléger des surplus comme les nodes
# que nous n'utilisons pas ici
bloques_edges=$(cat "$chemin_vers_fichier" | sed -n -e "/<edge/,/<\/edge>/ p" | tr -d "\n" | sed -s 's+</edge>+</edge>\n+g')


# affichage préalable du nombre de rues total dans le fichier pour anticiper le temps d'éxécution
echo "il y a $(echo $list_rues_noms | wc --words) rues au total"

#transformation du nom des rues en tableau
array=()
for i in $list_rues_noms
do
        array+=("$i")
done

#Pour paralléliser le processus nous allons diviser le tableau de nom de rues en sous tableaux. La taille des sous
# tableaux est définici-dessous
let "taille = ${#array[@]}/10"

#supprimmer l'ancien fichier sortie contenant les résultats de l'ancienne execution
rm sortie

#boucle de parallélisation d'appel à la fonction recupere_info
for((i=0; i < ${#array[@]}; i+=taille))
do
  part=( "${array[@]:i:taille}" )
  recupere_info "${part[@]}" &
done
# attente des processus pas encore fini
wait

# calcul du nombre de rues possédant les paramètres recherchés
nb_rues_avec_info_final=$(cat ./sortie | grep '-' | wc -l)
echo "il y a $nb_rues_avec_info_final rues avec une des variables a garder sur ${#array[@]} au total"
for id_osm in "${!tab_identifiant_osm_a_garder[@]}"
do
    echo "$id_osm : $(cat sortie | grep "${tab_identifiant_osm_a_garder[$id_osm]}" | wc -l) sur ${#array[@]}"
done