#!/bin/bash

# VARIABLES GLOBALES
CONF_FILE="/etc/MagistralVPN/vpn.conf"
VERSION="v1.0.1"
AUTEUR="NoahLgrd"

LOGS_DIR="/etc/MagistralVPN/logs"
LOGS_FILE="$LOGS_DIR/update_$(date '+%d-%m-%Y_%H:%M:%S').log"

# Regex pour détecter un nombre
re='^[0-9]+$'

# Affiche un "logo" en ASCII Art de MagistralVPN
asciiArtMenu() {
    echo -e "\e[32m  __  __             _     _             ___      _______  _   _ "
    echo " |  \/  |           (_)   | |           | \ \    / /  __ \| \ | |"
    echo " | \  / | __ _  __ _ _ ___| |_ _ __ __ _| |\ \  / /| |__) |  \| |"
    echo " | |\/| |/ _' |/ _  | / __| __| '__/ _' | | \ \/ / |  ___/| . ' |"
    echo " | |  | | (_| | (_| | \__ \ |_| | | (_| | |  \  /  | |    | |\  |"
    echo " |_|  |_|\__,_|\__, |_|___/\__|_|  \__,_|_|   \/   |_|    |_| \_|"
    echo "                __/ |                                            "
    echo -e "               |___/                                             \e[0m"
    echo ""
    echo ""
    echo -e "\e[36m$VERSION - $AUTEUR \e[0m"
}

# Récupère la valeur d'une clé passée en paramètre
getValeurCle() {
    local key="$1"
    local file=$CONF_FILE
    local value=$(grep -E "^$key=" "$file" | cut -d'=' -f2-)

    echo "$value"
}

# Modifie la valeur d'une clé passée en paramètre
setValeurCle() {
    local key="$1"
    local file="$CONF_FILE"
    local value="$2"

    if [[ ! -f "$file" ]]; then
        echo "Erreur : Le fichier $file n'existe pas."
        return 1
    fi

    # Vérifier si la clé existe déjà
    if grep -q "^$key=" "$file"; then
        sudo sed -i "s|^$key=.*|$key=$value|" "$file"
    else
        # Ajouter la clé si elle n'existe pas
        echo "$key=$value" >> "$file"
    fi
}

# Génère le fichier client
genererFichierClient() {
    local ip_client="$1"
    local ip_serveur_pb="$2"
    local port="$3"
    local fichier="$4"
    local cle_client_prive="$5"
    local cle_serveur_public="$6"

    echo "[Interface]" >> "$fichier"
    echo "PrivateKey = $cle_client_prive" >> "$fichier"
    echo "Address = $ip_client"/24 >> "$fichier"
    echo "" >> "$fichier"
    echo "[Peer]" >> "$fichier"
    echo "PublicKey = $cle_serveur_public" >> "$fichier"
    echo "Endpoint = $ip_serveur_pb:$port" >> "$fichier"
    echo "AllowedIPs = 0.0.0.0/0" >> "$fichier"
    echo "PersistentKeepalive = 15" >> "$fichier"
}

# Génère le fichier serveur
genererFichierServeur() {
    local ip_serveur="$1"
    local port_serveur="$2"
    local ip_client="$3"
    local fichier="$4"
    local cle_serveur_prive="$5"
    local cle_client_public="$6"

    echo "[Interface]" >> "$fichier"
    echo "PrivateKey = $cle_serveur_prive" >> "$fichier"
    echo "Address = $ip_serveur" >> "$fichier"
    echo "ListenPort = $port_serveur" >> "$fichier"
    echo "" >> "$fichier"
    echo "[Peer]" >> "$fichier"
    echo "PublicKey = $cle_client_public" >> "$fichier"
    echo "AllowedIPs = $ip_client"/32 >> "$fichier"
}

# Génère le fichier README pour la paire de connexion
genererReadmePaire() {
    local profil="$1"
    local fichier_serveur="$2"
    local fichier_client="$3"
    echo "# Fichiers .conf #" >> README_${profil}.md
    echo "Client : renommer $fichier_client en $profil.conf et le déplacer dans '/etc/wireguard/'" >> README_${profil}.md
    echo "Serveur : renommer $fichier_serveur en $profil.conf et le déplacer dans '/etc/wireguard/ (dans la partie serveur)'" >> README_${profil}.md
    echo "------- : puis 'sudo wg-quick up $profil'" >> README_${profil}.md
    echo "------- : puis 'sudo systemctl enable wg-quick@$profil'" >> README_${profil}.md
    echo "Client : se connecter avec MagistralVPN puis option 1" >> README_${profil}.md
}

# Génère le fichier README pour un nouveau client
genererReadmeClient() {
    local profil="$1"
    local fichier_temp="$2"
    echo "# Fichiers .conf #" >> README_${profil}.md
    echo "Client : renommer ${profil}_client.conf en $profil.conf et le déplacer dans '/etc/wireguard/'" >> README_${profil}.md
    echo "Serveur : Récupérer le bloc dans temp_serv.conf, puis l'ajouter dans le fichier"  >> README_${profil}.md
    echo "--------  de configuration du serveur." >> README_${profil}.md
    echo "Client : se connecter avec MagistralVPN puis option 1" >> README_${profil}.md
}

# Double authentification
2FA() {
    # 2FA=$(getValeurCle "2FA")
    # ...
    # À implémenter dans gestionnaire()
    # si 2FA neq NON alors on continue
    # sinon, on active cette fonction
    # ...
    echo "coucou" &> /dev/null
}

# Menu d'affichage
menu() {
    clear
    asciiArtMenu
    echo ""
    echo ""
    echo -e "\e[32m[1] Activer/Désactiver le VPN"
    echo "[2] Créer une connexion"
    echo "[3] Modifier les paramètres"
    echo ""
    echo -e "[Q] Quitter"
    echo ""
    read -p ">> " choix
    echo -e "\e[0m"
    gestionnaire "$choix"
}

# Gestionnaire des options, lié au menu d'affichage
gestionnaire() {
    local choix="$1"
    if ! [[ $choix =~ $re ]]; then
        # [Q] Quitter
        if [[ $choix == "Q" ]] || [[ $choix == "q" ]]; then
            echo "Au revoir !"
            sleep 1
            clear
            exit 0
        fi
        echo "[ERR] $choix n'est pas une option valide"
        sleep 1
        menu
    else
        # [1] Activer/Désactiver le VPN
        if [ $choix -eq 1 ]; then
            DEFAULT_PROFILE=$(getValeurCle "DEFAULT_PROFILE")
            if ip link show $DEFAULT_PROFILE &> /dev/null; then
                sudo wg-quick down $DEFAULT_PROFILE &> /dev/null
                echo "[*] VPN désactivé"
                sleep 2
                menu
            else
                if [[ $DEFAULT_PROFILE == "???" ]]; then
                    echo "La valeur du profil par défaut n'est pas définie."
                    echo "Veuillez la définir dans ''Menu > 3''"
                    sleep 3
                    menu
                else
                    sudo wg-quick up $DEFAULT_PROFILE &> /dev/null
                    echo "[*] VPN activé"
                    sleep 2
                    menu
                fi
            fi
        # [2] Créer une connexion
        elif [ $choix -eq 2 ]; then
            menu_connexion() {
                clear
                echo -e "\e[32m[1] Nouveau client (pour un serveur déjà configuré)"
                echo "[2] Paire client-serveur"
                echo "[M] Menu"
                read -p ">> " choix_connexion

                # [1] Nouveau client (pour un serveur déjà configuré)
                if [ "$choix_connexion" = "1" ]; then
                    clear
                    echo "[*] Entrer le nom du profil"
                    read -p ">> " nom_profil
                    echo ""
                    echo "[*] Entrer l'IP du client sans /CIDR (privée)"
                    read -p ">> " ip_client
                    echo ""
                    echo "[*] Entrer l'IP du serveur (public)"
                    read -p ">> " ip_serveur_public
                    echo ""
                    echo "[*] Entrer le port du serveur"
                    read -p ">> " port_serveur
                    echo ""
                    echo "[*] Entrer la clé publique du serveur"
                    echo "(il était conseillé de la conserver lors de la création initiale)"
                    echo "(récupérable dans le fichier .conf du serveur sinon)"
                    read -p ">> " cle_serv_pub
                    echo ""

                    # Générations des clés
                    echo "[*] Génération des clés en cours ..."
                    wg genkey | tee client_private.key | wg pubkey > client_public.key
                    echo "[*] Clés du client générées !"
                    echo "------------------------------------"

                    # Récupération de la clé
                    cle_cli_priv=$(cat client_private.key)
                    cle_cli_pub=$(cat client_public.key)

                    # Attribution du nom de fichier
                    nom_profil_client=$nom_profil"_client.conf"

                    if [[ $is_defaut == "OUI" ]]; then
                        setValeurCle "DEFAULT_PROFILE" "$nom_profil"
                    fi

                    genererFichierClient "$ip_client" "$ip_serveur_public" "$port_serveur" "$nom_profil_client" "$cle_cli_priv" "$cle_serv_pub"
                    echo "[*] Fichier client généré !"
                    echo ""
                    genererReadmeClient "$nom_profil"
                    mkdir $nom_profil
                    echo "[Peer]" >> "temp_serv.conf"
                    echo "PublicKey = $cle_cli_pub" >> "temp_serv.conf"
                    echo "AllowedIPs = $ip_client" >> "temp_serv.conf"
                    mv client_public.key client_private.key temp_serv.conf README_${nom_profil}.md $nom_profil_client $nom_profil/
                    echo "[*] Les clés et les .conf ont été déplacées dans le répertoire ${nom_profil}"
                    echo "------------------------------------"
                    echo -e "\e[0m"
                    sleep 2
                    menu
                # [2] Paire client-serveur
                elif [ "$choix_connexion" = "2" ]; then
                    clear
                    echo -e "\e[32m[*] Entrer le nom du profil"
                    read -p ">> " nom_profil
                    echo ""
                    echo "[*] Profil par défaut ? (OUI ou NON)"
                    read -p ">> " is_defaut
                    echo ""
                    echo "[*] Entrer l'IP du serveur (public)"
                    read -p ">> " ip_serveur_public
                    echo ""
                    echo "[*] Entrer le port du serveur"
                    read -p ">> " port_serveur
                    echo ""
                    echo "[*] Entrer l'IP du serveur /XX (privée)"
                    echo "(Il s'agit de l'IP/XX qu'aura le serveur VPN sur le réseau interne)"
                    read -p ">> " ip_serveur_privee
                    echo ""
                    echo "[*]  Entrer l'IP du client sans /CIDR (privée)"
                    read -p ">> " ip_client
                    echo ""

                    # Générations des clés
                    echo "[*] Génération des clés en cours ..."
                    wg genkey | tee server_private.key | wg pubkey > server_public.key
                    echo "[*] Clés du serveur générées !"
                    wg genkey | tee client_private.key | wg pubkey > client_public.key
                    echo "[*] Clés du client générées !"
                    echo "------------------------------------"

                    # Récupération des clés
                    cle_cli_pub=$(cat client_public.key)
                    cle_cli_priv=$(cat client_private.key)
                    cle_serv_pub=$(cat server_public.key)
                    cle_serv_priv=$(cat server_private.key)

                    # Attribution des noms de fichier
                    nom_profil_serveur=$nom_profil"_serveur.conf"
                    nom_profil_client=$nom_profil"_client.conf"

                    if [[ $is_defaut == "OUI" ]]; then
                        setValeurCle "DEFAULT_PROFILE" "$nom_profil"
                    fi

                    genererFichierServeur "$ip_serveur_privee" "$port_serveur" "$ip_client" "$nom_profil_serveur" "$cle_serv_priv" "$cle_cli_pub"
                    echo "[*] Fichier serveur généré !"
                    genererFichierClient "$ip_client" "$ip_serveur_public" "$port_serveur" "$nom_profil_client" "$cle_cli_priv" "$cle_serv_pub"
                    echo "[*] Fichier client généré !"
                    genererReadmePaire "$nom_profil" "$nom_profil_serveur" "$nom_profil_client"
                    mkdir $nom_profil
                    mv client_public.key client_private.key server_public.key server_private.key README_${nom_profil}.md $nom_profil_serveur $nom_profil_client $nom_profil/
                    echo "[*] Les clés et les .conf ont été déplacées dans le répertoire ${nom_profil}"
                    echo "[!] N'oubliez pas de garder de côté les 4 clés en cas de problèmes/prochaines configuration"
                    echo "------------------------------------"
                    echo -e "\e[0m"
                    sleep 2
                    menu
                elif [[ "$choix_connexion" == "M" ]] || [[ $choix_connexion = "m" ]]; then
                    menu
                else
                    echo "[ERR] $choix_connexion n'est pas une option valide"
                    sleep 2
                    menu_connexion
                fi
            }
            menu_connexion
        # [3] Modifier les paramètres
        elif [ $choix -eq 3 ]; then
            menu_parametre() {
                clear
                echo -e "\e[32m[1] MagistralVPN"
                echo "[2] WireGuard"
                echo "[M] Menu"
                read -p ">> " choix_parametre
                echo -e "\e[0m"
                # [1] Ouvre le fichier de conf vpn.conf
                if [ "$choix_parametre" = "1" ]; then
                    sudo nano $CONF_FILE
                    menu_parametre
                # [2] Ouvre le fichier de conf de WireGuard, selon le profil définit dans les paramètres par défaut
                elif [ "$choix_parametre" = "2" ]; then
                    DEFAULT_PROFILE=$(getValeurCle "DEFAULT_PROFILE")
                    echo "$DEFAULT_PROFILE"
                    if [ -z "$DEFAULT_PROFILE" ]; then
                        echo "[!] Le profil par défaut doit être définit !"
                        sleep 2
                        menu_parametre
                    fi
                    sudo nano /etc/wireguard/"$DEFAULT_PROFILE".conf
                menu_parametre
                elif [[ "$choix_parametre" == "M" ]] || [[ $choix_parametre = "m" ]]; then
                    menu
                else
                    echo "[ERR] $choix_parametre n'est pas une option valide"
                    sleep 2
                    menu_parametre
                fi
            }
            menu_parametre
        # [4] Mettre à jour
        elif [ $choix -eq 4 ]; then
            update
            exit 0
        fi
    fi
}
sudo -v
menu
