#!/bin/bash

# ==========================Variables==========================

# Liste des cartes réseaux	
eth=("eth0" "eth1")

# Version de Debian
debian_required=11

# Liste des paquets à installer
paquets=("netcat" "curl" "tmux" "vim" "sngrep" "net-tools" "mtr" "htop" "atop" "postgresql-client" "hdparm" "tshark" "bc")

# Liste des URLs système
system_url=("http://mirror.xivo.solutions/xivo_install.sh" "https://download.docker.com/linux/debian/gpg" "https://www.postgresql.org/media/keys/ACCC4CF8.asc" "http://deb.debian.org/debian/" "https://github.com/docker/compose/releases")

# Liste des URLs docker
docker_url=("https://hub.docker.com" "https://docker.io" "https://download.docker.com" "https://registry-1.docker.io" "https://docker.elastic.co" "https://production.cloudflare.docker.com" "https://github.com" "https://s3-1-w.amazonaws.com" "https://gitlab.com")

# Liste des proxies et leurs paths
declare -A proxies
proxies["CURL"]=~/.curlrc
proxies["wget"]=~/.wgetrc
proxies["docker"]=/etc/systemd/system/docker.service.d/http-proxy.conf
proxies["apt"]=/etc/apt/apt.conf.d/90proxy

# Liste des ports à tester sur le PBX
ports_pbx=("9100" "5039" "5672" "5003" "5038" "9497" "9489" "9486" "9487" "5432" "25")
# Liste des ports à tester sur le CC
ports_cc=("873" "5443")

#==========================Fonctions==========================

###########Fonctions d'initialisation des variables###########

# Fonction permettant de déterminer le type d'installation (PBX ou CC)
xivo_type(){
  echo "Choisissez le type d'installation XiVO à vérifier"
  echo "1) XiVOPBX"
  echo "2) XiVOCC"
  read xivotype
  case $xivotype in
    [1]*) echo "Vous avez choisi XiVOPBX";;
    [2]*) echo "Vous avez choisi XiVOCC";;
    *) echo -e "\033[0;31m Erreur, tapez '1' pour XIVOPBX ou '2' pour XIVOCC \033[0m"
      exit 1;;
  esac
}

# Cette fonction détermine si l'architecture et de type PBX seulement ou PBX+CC
xivo_pbx_cc(){
  if [ $xivotype -eq 1 ]
  then
    # Choix des spécifités du PBX
    echo "Voulez-vous tester vote PBX tout seul ou souhaitez vous tester la connexion avec le CC ?"
    echo "1) XiVOPBX seul"
    echo "2) XiVOPBX avec test de connexion vers le CC"
    read xivopbxcc
    case $xivopbxcc in
      [1]*) echo "Vous avez choisi de tester le XiVOPBX seul";;
      [2]*) echo "Vous avez choisi de tester XiVOPBX, ainsi que sa connexion avec le CC";;
      *) echo -e "\033[0;31m Erreur, veuillez choisir des options acceptés ('1' pour XiVOPBX seul ou '2' pour XiVOPBX avec test de connexion vers le CC) \033[0m"
        exit 1;;
    esac
  else
    # Choix des spécifités du CC
    echo "Voulez-vous tester vote CC tout seul ou souhaitez vous tester la connexion avec le PBX ?"
    echo "1) XIVOCC seul"
    echo "2) XIVOCC avec test de connexion vers le PBX"
    read xivopbxcc
    case $xivopbxcc in
      [1]*) echo "Vous avez choisi de tester le XIVOCC seul";;
      [2]*) echo "Vous avez choisi de tester XIVOCC, ainsi que sa connexion avec le PBX";;
      *) echo -e "\033[0;31m Erreur, veuillez choisir des options acceptés ('1' pour XIVOCC seul ou '2' pour XIVOCC avec test de connexion vers le PBX) \033[0m"
        exit 1;;
    esac
  fi
}

# Cette fonction est utilisée dans le cas de l'installation PBX pour déterminer les ressources nécessaires selon le nombre d'utilisateurs
xivo_pbx_requirements(){
    echo "Combien d'utilisateurs avez-vous ? (Ceci est pour déterminer les ressources nécessaires) :"
    echo "1) Jusqu'à 500 utilisateurs"
    echo "2) Jusqu'à 500 utilisateurs Grande Capacité"
    echo "3) Jusqu'à 500 utilisateurs CC"
    echo "4) Jusqu'à 1000 utilisateurs"
    echo "5) Jusqu'à 1000 utilisateurs Grande Capacité"
    read users
    case $users in
      [1]*) echo "Vous avez jusqu'à 500 utilisateurs !"
            cpu_min=6
            ram_min=6
            disk_min=80
            ;;
      [2]*) echo "Vous avez jusqu'à 500 utilisateurs Grande Capacité !"
            cpu_min=8
            ram_min=8
            disk_min=120
            ;;
      [3]*) echo "Vous avez jusqu'à 500 utilisateurs CC !"
            cpu_min=12
            ram_min=12
            disk_min=120
            ;;
      [4]*) echo "Vous avez jusqu'à 1000 utilisateurs !"
            cpu_min=8
            ram_min=8
            disk_min=80
            ;;
      [5]*) echo "Vous avez jusqu'à 1000 utilisateurs Grande Capacité !"
            cpu_min=12
            ram_min=12
            disk_min=120
            ;;
      *) echo -e "\033[0;31m Erreur, veuillez choisir une options acceptée (de '1' à '5') \033[0m"
        exit 1;;
    esac
    echo  "Vous avez besoin de : $cpu_min CPUs, $ram_min GO de RAM et $disk_min GO d'espace disque" | tee -a pre_requis.log
}

# Fonction est utilisée dans le cas de l'installation CC pour déterminer les ressources nécessaires selon le nombre d'agents
xivo_cc_requirements(){
    echo "Combien d'agents avez-vous ? (Ceci est pour determiner l'architecture et les ressources nécessaires) :"
    echo "1) Jusqu'à 25 agents"
    echo "2) Entre 25 et 75 agents"
    echo "3) Plus de 75 agents"
    read agents
    case $agents in
      [1]*) echo "Vous avez jusqu'à 25 agents, nous allons utiliser l'architecture CC complet (1 serveur) !"
            cpu_min=6
            ram_min=8
            echo "Allez vous utiliser les enregistrements ?"
            echo "1) OUI"
            echo "2) NON"
            read recordings
            case $recordings in
                [1]*) echo "Vous utilisez les enregistrements !"
                        disk_min=240
                        ;;
                [2]*) echo "Vous n'utilisez pas les enregistrements !"
                        disk_min=120
                        ;;
                *) echo -e "\033[0;31m Erreur, veuillez choisir l'option '1' si vous utilisez des enregistrements, sinon choisissez l'option '2' \033[0m"
                exit 1
                ;;
            esac
            ;;
      [2]*) echo "Vous avez entre 25 et 75 agents, nous allons utiliser l'architecture XuC/Backend (2 serveurs) !"
            echo "Est-ce que ce serveur sera utilisé pour le XuC ou pour le Backend ?"
            echo "1) XuC"
            echo "2) Backend"
            read serv_type
            case $serv_type in
                [1]*) echo "Ce serveur sera pour le XuC !"
                        cpu_min=4
                        ram_min=6
                        disk_min=80
                        ;;
                [2]*) echo "Ce serveur sera pour le Backend !"
                        cpu_min=6
                        ram_min=6
                        disk_min=240
                        ;;
                *) echo -e "\033[0;31m Erreur, veillez taper '1' si ce serveur sera pour le Xuc ou '2' si il sera pour le Backend \033[0m"
                exit 1
                ;;
            esac
            ;;
      [3]*) echo "Vous avez plus de 75 agents, nous allons utiliser l'architecture XuC/Reporting/Recording (3 serveurs) !"
            echo "Est-ce que ce serveur sera utilisé pour le XuC ou pour le Backend ?"
            echo "1) XuC"
            echo "2) Reporting"
            echo "2) Recording"
            read serv_type
            case $serv_type in
                [1]*) echo "Ce serveur sera pour le XuC !"
                        cpu_min=6
                        ram_min=8
                        disk_min=80
                        ;;
                [2]*) echo "Ce serveur sera pour le Reporting !"
                        cpu_min=6
                        ram_min=6
                        disk_min=160
                        ;;
                [3]*) echo "Ce serveur sera pour le Recording !"
                        cpu_min=4
                        ram_min=4
                        disk_min=800
                        ;;
                *) echo "\033[0;31m Erreur, choisissez une option acceptée ('1', '2' ou '3')"
                exit 1
                ;;
            esac
            ;;
      *) echo -e "\033[0;31m Erreur, choisissez une option acceptée ('1', '2' ou '3') \033[0m"
        exit 1;;
    esac
    echo "Vous avez besoin de : $cpu_min CPUs, $ram_min GO de RAM et $disk_min GO d'espace disque" | tee -a pre_requis.log
}

# Fonction qui récupere l'hôte distant (Le CC si l'installation est pour un PBX et vice versa)
dist_host_ip(){
  # Récupération de l'IP et du FQDN dans le cas d'une utilisation multi-serveurs
  echo "Entrez l'IP ou le FQDN du serveur distant"
  read disthost
}

# Cette fonction détermine si les tests de performances seront effectués
test_perf_enabled(){
  echo "Souhaitez-vous effectuer un test de performance (la durée moyenne de ce test est de 10 min)"
  echo "1) Oui"
  echo "2) Non"
  read testperf
  case $testperf in
    [1]*) echo "Le test de performance sera effectué";;
    [2]*) echo "Le test de performance ne sera pas effectué";;
    *) echo -e "\033[0;31m Erreur, tapez '1' pour les tests de performance, sinon tapez '2' \033[0m"
      exit 1;;
  esac
}

###########Fonction de conformité système###########

# Fonction qui vérifie si le système est compatible pour l'installation de Xivo
check_system(){
	echo ""
	echo "Vérification de la conformité du système" | tee -a pre_requis.log

	if [ -e "/etc/debian_version" ] && ! grep -q '[a-zA-Z]' "/etc/debian_version"; #Check if the OS is Debian with the right syntax (Not Ubuntu or Mint)
	then

		debian_version=$(cat /etc/debian_version)
		if [ $(echo $debian_version | cut -d "." -f 1) -eq $debian_required ] #Check if the version is Debian 11
		then

			echo -e "\033[0;32m Version Debian OK : $debian_version \033[0m" | tee -a pre_requis.log
		else
			echo -e " \033[0;31m Version Debian Non-OK : $debian_version \033[0m" | tee -a pre_requis.log
		fi

		INTERFACE_GRAPHIQUE=$(dpkg -l | grep xserver)
                if [ -z "$INTERFACE_GRAPHIQUE" ]; then
			echo -e "\033[0;32m Aucune GUI n'est installée \033[0m" | tee -a pre_requis.log
		else
			echo -e " \033[0;31m Une GUI est installée \033[0m" | tee -a pre_requis.log
		fi
	else
				echo -e "\033[0;31m OS non supporté \033[0m" | tee -a pre_requis.log
	fi
}

###########Fonction de conformité réseau###########

# Cette fonction vérifie la disponibilité d'interfaces réseaux avec les bonne nominations 
check_interfaces(){
	echo ""
	echo "Vérification du nommage des interfaces réseaux" | tee -a pre_requis.log

	# Boucle sur les cartes réseaux
	for i in "${eth[@]}" 
	do

			# Récupération des informations sur les cartes réseaux
        	ip_eth=$(ip a | grep $i)
	        
			# Si des informations sont disponibles pour la carte, on affiche que tout est OK, sinon, on affiche que ce n'est pas OK
	        if [ -n "$ip_eth" ]
        	then
                	echo -e "\033[0;32m Interface réseau $i OK \033[0m" | tee -a pre_requis.log
	        else
        	        echo -e "\033[0;31m Interface réseau $i Non-OK \033[0m" | tee -a pre_requis.log
	        fi

	done
}

###########Fonctions de vérification apt et d'installation de paquets nécessaires pour Xivo###########

# Fonction vérifiant que le source.list est conforme
apt_checks(){
        echo ""
        echo "Vérification de la conformité d'apt" | tee -a pre_requis.log
        SOURCE_LIST_COMPATIBILITY="$(cat /etc/apt/sources.list | grep deb.debian.org | grep -v "#")$(cat /etc/apt/sources.list | grep fr.debian.org | grep -v "#")"

        if [ -z "$SOURCE_LIST_COMPATIBILITY" ];
        then
                echo -e "\033[0;31m Le fichier sources.list n'est pas conforme \033[0m" | tee -a pre_requis.log
        else
                echo -e "\033[0;32m Le fichier sources.list est conforme \033[0m" | tee -a pre_requis.log
        fi
}

# Cette fonction vérifie si les paquets nécessaires sont installés et sinon, les installe
packages_checks_and_install(){
        echo ""
        echo "Mise à jour de la liste des paquets"
        apt update

        echo ""
        echo "Vérification de la présence des paquets APT" | tee -a pre_requis.log

        # Boucle sur les paquets à installer
        for i in "${paquets[@]}"
        do
                # Test de la présence du paquet sur le système et installation de celui-ci si ce n'est pas le cas
                if ! dpkg -l | grep -q "ii  $i ";
                then
                        echo -e "\033[0;31m $i n'est pas installé, installation ! \033[0m" | tee -a pre_requis.log
                        DEBIAN_FRONTEND=noninteractive apt install -y $i
                else
                        echo -e "\033[0;32m $i est installé ! \033[0m" | tee -a pre_requis.log
                fi

        done
}

###########Fonctions de vérification de la conformité du hostname###########

# Fonction qui vérifie si le hostname existe dans /etc/hostname
check_hostname_conformity(){
	echo ""
	echo "Vérification du hostname" | tee -a pre_requis.log

	# Vérification de la cohérence entre la commande hostname et /etc/hostname
	if [ $(echo $(hostname)) = $(cat /etc/hostname) ]
	then
		echo -e "\033[0;32m hostname et /etc/hostname identique \033[0m" | tee -a pre_requis.log
	else
		echo -e "\033[0;31m hostname et /etc/hostname non identique \033[0m" | tee -a pre_requis.log
	fi
}

# Cette fonction vérifie que le hostname est présent dans la listes des hosts dans /etc/hosts
check_hostname_configuration(){
	# Vérification de la présence du hostname configuré dans /etc/hostname dans /etc/hosts
	if [ -n "$(cat /etc/hosts | grep -w $(cat /etc/hostname))" ]
	then
			echo -e "\033[0;32m /etc/hostname présent dans /etc/hosts \033[0m" | tee -a pre_requis.log
	else
			echo -e "\033[0;31m /etc/hostname non présent dans /etc/hosts \033[0m" | tee -a pre_requis.log
	fi
}

# Cette fonction vérifie si le hostname contient ou non des caractères majuscules
check_hostname_syntax(){
# Vérification de la présence de majuscule dans le hostname
	if [[ ! $(cat /etc/hostname) =~ [A-Z] ]]
	then
		echo -e "\033[0;32m hostname ne contient pas de majuscules \033[0m" | tee -a pre_requis.log
	else
		echo -e "\033[0;31m hostname contient des majuscules \033[0m" | tee -a pre_requis.log
	fi
}

###########Fonctions de vérification de l'accès aux URLs systèmes et docker via wget et curl###########

# Fonction qui test l'accès aux URLs systèmes via wget et curl
test_system_urls(){
        echo ""
        echo "Test des URLs système" | tee -a pre_requis.log

        # Boucle sur les URLs
        for i in "${system_url[@]}"
        do

                # Récupération des codes HTTP sur les URLs via curl et wget
                http_code_curl=$(curl -k -m 3 -I $i 2>/dev/null | head -n 1 | awk '{print $2}')
                http_code_wget=$(wget --no-check-certificate --tries=1 --timeout=3 --spider -S "$i" 2>&1 | grep "HTTP/" | tail -n -1 | awk '{print $2}')

                # Si le code CURL est innexistant (site qui ne réponds pas par exemple), on le défini à 0
                if [ -z $http_code_curl ]
                then
                        http_code_curl=0
                fi

                # Si le code wget est innexistant (site qui ne réponds pas par exemple), on le défini à 0
                if [ -z $http_code_wget ]
                then
                        http_code_wget=0
                fi

                # Si le code CURL est égal à 200, 301 ou 302, alors le site répond
                if [ $http_code_curl -eq 200 ] || [ $http_code_curl -eq 301 ] || [ $http_code_curl -eq 302 ]
                then
                        echo -e " CURL ->\033[0;32m URL : $i, CODE HTTP : $http_code_curl \033[0m " | tee -a pre_requis.log
                else
                        echo -e " CURL ->\033[0;31m URL : $i, CODE HTTP : $http_code_curl \033[0m " | tee -a pre_requis.log
                fi

                # Si le code wget est égal à 200, 301 ou 302, alors le site répond
                if [ $http_code_wget -eq 200 ] || [ $http_code_wget -eq 301 ] || [ $http_code_wget -eq 302 ]
                then
                        echo -e " WGET ->\033[0;32m URL : $i, CODE HTTP : $http_code_wget \033[0m " | tee -a pre_requis.log
                else
                        echo -e " WGET ->\033[0;31m URL : $i, CODE HTTP : $http_code_wget \033[0m " | tee -a pre_requis.log
                fi

        done
}

# Cette fonction permet de vérifier si on peut accèder aux URLs docker via wget et curl
test_docker_urls(){
        echo "Test des URLs docker" | tee -a pre_requis.log

        # Boucle sur les URLs
        for i in "${docker_url[@]}"
        do

                # Récupération des codes HTTP sur les URLs via curl
                http_code_curl=$(curl -k -m 3 -I $i 2>/dev/null | head -n 1 | awk '{print $2}')

                # Si le code CURL est innexistant (site qui ne réponds pas par exemple), on le défini à 0
                if [ -z $http_code_curl ]
                then
                        http_code_curl=0
                fi

                # Si le code CURL est égal à 200, 301, 302, 403 ou 404, alors le site réponds
                if [ $http_code_curl -eq 200 ] || [ $http_code_curl -eq 301 ] || [ $http_code_curl -eq 302 ] || [ $http_code_curl -eq 307 ] || [ $http_code_curl -eq 403 ] || [ $http_code_curl -eq 404 ]
                then
                        echo -e " CURL ->\033[0;32m URL : $i, CODE HTTP : $http_code_curl \033[0m " | tee -a pre_requis.log
                else
                        echo -e " CURL ->\033[0;31m URL : $i, CODE HTTP : $http_code_curl \033[0m " | tee -a pre_requis.log
                fi

        done
}

###########Fonctions de vérification des proxies###########

# Fonction pour tester la présence d'un fichier de configuration de proxy
check_proxies(){
	echo ""
	echo "Test du proxy" | tee -a pre_requis.log
	for proxy in "${!proxies[@]}";do
		file=$(basename "${proxies[$proxy]}")
		if [ -f "${proxies[$proxy]}" ]; then
			echo "Fichier $proxy ${file//\*} présent" | tee -a pre_requis.log
		else
			echo "Fichier $proxy ${file//\*}  absent" | tee -a pre_requis.log
		fi
	done
}

# Fonction qui test de la configuration du proxy Xivo
test_xivo_proxy(){
	echo ""
	if [ -f /etc/xivo/dhcpd-update.conf ]
	then
	        xivo_proxy=$(cat /etc/xivo/dhcpd-update.conf | grep "http: http://" | cut -c1 | tail -n -1)
        	if [ $xivo_proxy = ";" ]
	        then
        	        echo "Proxy http xivo non configuré" | tee -a pre_requis.log
	        else
        	        echo "Proxy http xivo configuré" | tee -a pre_requis.log
	        fi
	else
        	echo "Fichier xivo dhcpd-update.conf absent" | tee -a pre_requis.log
	fi
}

###########Fonctions de vérification des ports libres pour les communications PBX/CC###########

# Cette fonction test les ports libres sur le PBX
test_pbx_ports(){
	echo ""
        echo "Appuyez sur entrer sur XiVO PBX puis XiVO CC lorsque les deux serveurs sont à ce point"
        read next

        echo "Test de connectivité entre XiVO PBX et XiVO CC" | tee -a pre_requis.log

        if [ $xivotype -eq 1 ]
        then

                echo "Ouverture des ports sur XiVO PBX pour effectuer les tests de connexion"

                for i in "${ports_pbx[@]}"
                do

			if ! $(nc -z 127.0.0.1 $i)
			then
			        echo -e "\033[0;32m Port $i non utilisé \033[0m" | tee -a pre_requis.log
                        	echo "Port $i en cours de test"
                        	nc -w3 -lp $i &> /dev/null
			else
			        echo -e "\033[0;31m Port $i déjà utilisé \033[0m" | tee -a pre_requis.log
			fi

                done

        elif [ $xivotype -eq 2 ]
        then

                echo "Test de connexion vers le serveur XiVO CC"

                for i in "${ports_pbx[@]}"; 
                do
                if timeout 1 bash -c "cat < /dev/null > /dev/tcp/$disthost/$i" 2>/dev/null; then
                        echo -e "\033[0;32m Port $i ouvert \033[0m" | tee -a pre_requis.log
                else
                        echo -e "\033[0;31m Port $i fermé \033[0m" | tee -a pre_requis.log
                fi
                sleep 0.1
                done
        fi
}

# Cette fonction test les ports libres sur le CC
test_cc_ports(){
        echo "Appuyez sur entrer sur XiVO CC puis XiVO PBX lorsque les deux serveurs sont à ce point"
        read next

        echo "Test de connectivité entre XiVO CC et XiVO PBX" | tee -a pre_requis.log

        if [ $xivotype -eq 2 ]
        then

                echo "Ouverture des ports sur XiVO CC pour effectuer les tests de connexion"

                for i in "${ports_cc[@]}"
                do

                        if ! $(nc -z 127.0.0.1 $i)
                        then
                                echo -e "\033[0;32m Port $i non utilisé \033[0m" | tee -a pre_requis.log
                        	echo " Port $i en cours de test "
                        	nc -w3 -lp $i &> /dev/null
                        else
                                echo -e "\033[0;31m Port $i déjà utilisé \033[0m" | tee -a pre_requis.log
                        fi

                done

        elif [ $xivotype -eq 1 ]
        then

                echo "Test de connexion vers le serveur XiVO CC"

                for i in "${ports_cc[@]}"; 
                do
                if timeout 1 bash -c "cat < /dev/null > /dev/tcp/$disthost/$i" 2>/dev/null; then
                        echo -e "\033[0;32m Port $i ouvert \033[0m" | tee -a pre_requis.log
                else
                        echo -e "\033[0;31m Port $i fermé \033[0m" | tee -a pre_requis.log
                fi
                sleep 0.1
                done
        fi
}

###########Fonctions de vérification des spécificités du système et des performances###########

# Fonction qui initialise l'état du système à "compatible"
setup_system_checks(){
        # Vérification des spécificitées du système
        echo ""
        echo "Spécificitées du système" | tee -a pre_requis.log

        system_okay=true
}

# Fonction permettant la vérification de la compatibilité du cpu
cpu_check(){
        # Récupération du CPU
        cpu=$(cat /proc/cpuinfo | grep "^processor" | wc -l)

        if [[ $cpu -ge $cpu_min ]]
        then
                cpu_statut="\033[0;32mOK\033[0m"
        else
                cpu_statut="\033[0;31mNon-OK\033[0m"
                system_okay=false
        fi

        echo -e " CPU ($cpu_statut) -> $cpu vCPU " | tee -a pre_requis.log
}

# Fonction qui vérifie la RAM
ram_check(){
        # Récupération de la RAM
        ram=$(free --si -g | grep Mem: | awk '{print $2}')

        if [[ $ram -ge $ram_min ]]
        then
                ram_statut="\033[0;32mOK\033[0m"
        else
                ram_statut="\033[0;31mNon-OK\033[0m"
                system_okay=false
        fi

        echo -e " RAM ($ram_statut) -> $ram GO "| tee -a pre_requis.log
}

# Fonction pour vérifier l'espace disque du root "/"
root_disk_check(){
        # Récupération du disque /
        disk_root=$(df -hT / | tail -n -1 )
        disk_root_filesystem=$(echo "$disk_root" | awk '{print $2}')
        disk_root_size=$(echo "$disk_root" | awk '{print $3}')
        disk_root_size_unit=$(echo "$disk_root_size" | grep -oE '[A-Z]+')
        disk_root_size_value=$(echo "$disk_root_size" | grep -oE '[0-9]+' | head -n1)
        disk_root_free=$(echo "$disk_root" | awk '{print $5}')

        if [[ $disk_root_filesystem = "ext4" && ( ( $disk_root_size_value -ge 8 && "$disk_root_size_unit" == "G" ) || ( $disk_root_size_value -ge $((8/1000)) && "$disk_root_size_unit" == "T" ) ) ]]
        then
                disk_root_statut="\033[0;32mOK\033[0m"
        else
                disk_root_statut="\033[0;31mNon-OK\033[0m"
                system_okay=false
        fi

        echo -e " Disque / ($disk_root_statut) -> filesystem : $disk_root_filesystem, taille : $disk_root_size, libre : $disk_root_free "| tee -a pre_requis.log
}

# Fonction pour vérifier l'espace disque du path "/var"
var_disk_check(){
        # Récupération du disque /var
        disk_var=$(df -hT /var | tail -n -1 )
        disk_var_filesystem=$(echo "$disk_var" | awk '{print $2}')
        disk_var_size=$(echo "$disk_var" | awk '{print $3}')
        disk_var_size_unit=$(echo "$disk_var_size" | grep -oE '[A-Z]+')
        disk_var_size_value=$(echo "$disk_var_size" | grep -oE '[0-9]+'| head -n1)
        disk_var_free=$(echo "$disk_var" | awk '{print $5}')

        if [[ $disk_var_filesystem = "ext4" && ( ( $disk_var_size_value -ge $disk_min && "$disk_var_size_unit" == "G" ) || ( $disk_var_size_value -ge $((disk_min/1000)) && "$disk_var_size_unit" == "T" ) ) ]]
        then
                disk_var_statut="\033[0;32mOK\033[0m"
        else
                disk_var_statut="\033[0;31mNon-OK\033[0m"
                system_okay=false
        fi

        echo -e " Disque /var ($disk_var_statut) -> filesystem : $disk_var_filesystem, taille : $disk_var_size, libre : $disk_var_free "| tee -a pre_requis.log
}

# Fonction affichant les résultats finales des spécificitées système
system_check_result(){
        # Génération du statut OK / NOK
        if $system_okay;
        then
                spec="{{OK}}"
        else
                spec="{{NOK}}"
        fi

        # Génération du rapport wiki
        echo "" | tee -a pre_requis.log
        echo "Export pour fiche wiki" | tee -a pre_requis.log
        echo "== Pré-requis VM ==" | tee -a pre_requis.log
        echo '{| class="wikitable sortable" style="text-align: center; width: 75%;"' | tee -a pre_requis.log
        echo "! Serveur !! CPU !! RAM !! DISQUE / !! DISQUE /var !! Statut" | tee -a pre_requis.log
        echo "|-" | tee -a pre_requis.log
        echo "| $(hostname) || $cpu vCPU || $ram GO || $disk_root_size $disk_root_filesystem || $disk_var_size $disk_var_filesystem || $spec" | tee -a pre_requis.log
        echo "|}" | tee -a pre_requis.log
}

# Fonction qui test les performances du disque
disk_speed_test(){
        error_write=0
        error_read=0
        results_write=""
        results_read=""
        echo "Test d'écriture et de lecture de disque :" | tee -a pre_requis.log
        for i in $(seq 1 1 3)
        do
        disk_write_spec=$(dd if=/dev/zero of=/tmp/hardware.txt bs=1M count=1000 conv=fdatasync 2>&1)
        disk_write_unit=$(echo $disk_write_spec | awk '{print $NF}')
        disk_write_value=$(echo $disk_write_spec | awk '{print $(NF-1)}' | tr ',' '.')

        if [ "$disk_write_unit" == "GB/s" ]; then
                disk_write_value=$(echo "$disk_write_value * 1024" | bc)
        fi

        disk_write_value=$(echo "$disk_write_value" | cut -d'.' -f1)
        if [ $disk_write_value -lt 200 ]; then
                error_write=1
                error_global=1
        fi

        write_result="$write_result/$disk_write_value"

        sleep 30

        disk_read_spec=$(dd if=/tmp/hardware.txt of=/dev/null bs=1M count=1000 2>&1)
        disk_read_unit=$(echo $disk_read_spec | awk '{print $NF}')
        disk_read_value=$(echo $disk_read_spec | awk '{print $(NF-1)}' | tr ',' '.')

        if [ "$disk_read_unit" == "GB/s" ]; then
                disk_read_value=$(echo "$disk_read_value * 1024" | bc)
        fi

        disk_read_value=$(echo "$disk_read_value" | cut -d'.' -f1)

        if [ $disk_read_value -lt 200 ]; then
                error_read=1
                error_global=1
        fi
        
        read_result="$read_result/$disk_read_value"

        sleep 30
        done
}

# Fonction affichant résultats des tests du disque
disk_speed_result(){
        write_result="${write_result#*/}"
        read_result="${read_result#*/}"

        if [ $error_write -eq 0 ]
        then
                echo -e "\033[0;32m Test d'écriture passé avec succès : $write_result \033[0m" | tee -a pre_requis.log
        else
                echo -e "\033[0;31m Test d'écriture en erreur : $write_result \033[0m" | tee -a pre_requis.log
        fi

        if [ $error_read -eq 0 ]
        then
                echo -e "\033[0;32m Test de lecture passé avec succès : $read_result \033[0m" | tee -a pre_requis.log
        else
                echo -e "\033[0;31m Test de lecture en erreur : $read_result \033[0m" | tee -a pre_requis.log
        fi

        rm -rf /tmp/hardware.txt

}


# Fonction qui lance les tests de cpu
cpu_test(){
        # Test du CPU
        echo ""
        echo "Test CPU :" | tee -a pre_requis.log

        for i in $(seq 1 1 3)
        do
                dd if=/dev/zero bs=1M count=1024 2>>/tmp/hardware.txt | md5sum 1>/dev/null
                sleep 30
        done
}

# Fonction affichant le résultat des tests de cpu
cpu_result(){
        # Récupération en brut des résultats
        error=0

        IFS=$'\n'
        for line in `cat /tmp/hardware.txt | grep "MB/s"`
        do

                line=$(echo $line | tail -c-10)
                line=${line:0:4}

                if [[ $line -lt 200 ]]
                then
                        error=1
			error_global=1
                fi

                cpu_result="$cpu_result/$line"

        done

        # Formatage du résultat cpu
        cpu_result=${cpu_result:2}
        cpu_result=$(echo $cpu_result | tr -d " ")

        # Affichage du résultat
        if [ $error -eq 0 ]
        then
                echo -e "\033[0;32m Test CPU passé avec succès : $cpu_result \033[0m" | tee -a pre_requis.log
        elif [ $error -eq 1 ]
        then
                echo -e "\033[0;31m Test CPU en erreur : $cpu_result \033[0m" | tee -a pre_requis.log
        fi

        # Suppression du fichier temporaire
        rm /tmp/hardware.txt
}

# Fonction qui affiche les résultats finaux des tests de performance
performance_tests_results(){
	# Génération du statut OK / NOK
	if [ $error_global -eq 0 ]
	then
	        perf="{{OK}}"
	elif [ $error_global -eq 1 ]
	then
	        perf="{{NOK}}"
	fi

        # Génération du rapport wiki
        echo "" | tee -a pre_requis.log
        echo "Export pour fiche wiki" | tee -a pre_requis.log
        echo "== Performances VM ==" | tee -a pre_requis.log
        echo '{| class="wikitable sortable" style="text-align: center; width: 75%;"' | tee -a pre_requis.log
        echo "! Serveur !! Ecriture !! Lecture !! CPU !! Statut" | tee -a pre_requis.log
        echo "|-" | tee -a pre_requis.log
        echo "| $(hostname) || $write_result || $read_result || $cpu_result || $perf" | tee -a pre_requis.log
        echo "|}" | tee -a pre_requis.log

}

# ==========================Execution==========================

# Appel des fonctions d'initialisation
xivo_type
xivo_pbx_cc

# Une de ces 2 fonctions va être exécuté selon le type du xivo
if [ $xivotype -eq 1 ]
then
	xivo_pbx_requirements
else
        xivo_cc_requirements
fi

# Si il y a un PBX et un CC, nous allons utiliser cette fonction pour déterminer l'hôte distant
if [ $xivopbxcc -ne 1 ]
then
  dist_host_ip
fi

# On vérifie si on effectue les tests de performances ou non
test_perf_enabled

# Maintenant, que tout est initialisé, on commence à tester la VM

# On check le système
check_system

# Si l'installation est pour un PBX, on check le nommage des interfaces
if [ $xivotype -eq 1 ]
then
	check_interfaces
fi

# Cette partie check l'apt et les installations
apt_checks
packages_checks_and_install

# On execute les vérifications sur le hostname
check_hostname_conformity
check_hostname_configuration
check_hostname_syntax

# On voit si les urls nécessaires pour l'installation de Xivo sont accessibles
test_system_urls
test_docker_urls

# Si nous sommes sur le PBX, on vérifie les proxies sur la VM
check_proxies
if [ $xivotype -eq 1 ]
then
	test_xivo_proxy
fi

# Si nous avons un PBX et un CC, on vérifie la connexion entre eux via les ports
if [ $xivopbxcc -ne 1 ]
then
        test_pbx_ports
        test_cc_ports
fi

# Cette partie concerne les tests de hardware
setup_system_checks
cpu_check
ram_check
root_disk_check
var_disk_check
# Ici, les résultats de ces tests vont être affichés
system_check_result

# Si l'utilisateur souhaite effectuer des tests de performance, cette partie est executée
if [ $testperf -eq 1 ]
then
        # Définition de la valeur error_global qui va définir la conformité globale
        error_global=0
        disk_speed_test
        disk_speed_result
        cpu_test
        cpu_result
        performance_tests_results
fi