#! /bin/bash

# TO RUN THIS SCRIPT :
# chmod u+x ./autoConnectLinuxMiNET.sh
# ./autoConnectLinuxMiNET.sh

# FOR EXTRA HELP :
# ./autoConnectLinuxMiNET.sh --help

# -----------------------------------------------------------------

# Checks if nmcli and cut are installed on the system :

nmcli --version 1>/dev/null 2>/dev/null
diditwork="$?"
if [ "$diditwork" -ne 0 ]; then
	echo "Fatal error : You are NOT using nmcli as your network manager !">&2
	echo "If you see this message, please come see us in person ! (and if you can't, please go to tickets.minet.net)">&2
	exit 4
fi
cut --version 1>/dev/null 2>/dev/null
diditwork="$?"
if [ "$diditwork" -ne 0 ]; then
	echo "Fatal error : the 'cut' command is not installed on your system !">&2
	echo "Install it and retry.">&2
	exit 4
fi
unset diditwork
ip link 1>/dev/null 2>/dev/null
diditwork="$?"
if [ "$diditwork" -ne 0 ]; then
	echo "Warning : the 'ip link' command seems to be missing on your computer. The program should still work, but might be missing some functionality" >&2
	iplink_is_present="false"
else
	iplink_is_present="true"
fi

partof () {
	#this function is the equivalent of 'x in ["choice1", "choice2", ...]' in python.
	#used like this : partof "$x" "choice1 choice2 choice3"
	if [ -z "$1" ]; then #dans une fonction, les paramètres sont $1, $2... indépendamment de ceux du programme !
		return 1
	fi
	for i in $2; do
		if [ "$1" == "$i" ]; then
			return 0
		fi
	done
	return 1
}

echolang() {
	#has three arguments : the language, what to show in english, what to show in french, and shows what must be shown
	#example usage : echolang "${args[arg_language]}" "What to say" "Ce qu'il y a à dire"
	if [ "$1" == en ]; then
		echo "$2"
	elif [ "$1" == fr ]; then
		echo "$3"
	else
		echo "The program must choose which option to show, but the language is not set ! This is a critical bug, please report it">&2
		exit 127
	fi
}

#A dictionnary (hashmap), work for bash --version >= 4
#args corresponds to the arguments used by the program, here with their default values
declare -A args=( ["arg_help"]="no" ["arg_verbose"]="no" ["arg_version"]="no" ["arg_language"]="prompt" ["arg_type"]="prompt" ["arg_on_existing"]="prompt" ["arg_mac"]="promptifmultiple" ["arg_check_for_wifi_mac_address"]="undecided" ["arg_no_wifi_mac_address_found"]="abort" ["arg_username"]="" ["arg_password"]="" ["arg_check_rfkill"]="yes" ["arg_use_iplink_if_available"]="yes" )
#possiblearguments corresponds to what the arguments can be set to
declare -A possiblearguments=( ["arg_language"]="en fr prompt" ["arg_type"]="ethernet wifi both prompt" ["arg_on_existing"]="abort delete prompt" ["arg_no_wifi_mac_address_found"]="abort warn" ["arg_check_rfkill"]="yes no" ["arg_use_iplink_if_available"]="yes no" )
#valid corresponds to what a flag will be read as
declare -A valid=( ["?"]="arg_help yes" ["h"]="arg_help yes" ["-h"]="arg_help yes" ["--h"]="arg_help yes" ["help"]="arg_help yes" ["-help"]="arg_help yes" ["--help"]="arg_help yes" ["-v"]="arg_verbose yes" ["--verbose"]="arg_verbose yes" ["-V"]="arg_version yes" ["--version"]="arg_version yes" ["-l"]="arg_language NEXT" ["--language"]="arg_language NEXT" ["-t"]="arg_type NEXT" ["--type"]="arg_type NEXT" ["-e"]="arg_on_existing NEXT" ["--on-existing"]="arg_on_existing NEXT" ["-m"]="arg_mac SPECIAL" ["--mac"]="arg_mac SPECIAL" ["-c"]="arg_check_for_wifi_mac_address yes" ["--check-for-wifi-mac-address"]="arg_check_for_wifi_mac_address yes" ["-C"]="arg_check_for_wifi_mac_address no" ["--dont-check-for-wifi-mac-address"]="arg_check_for_wifi_mac_address no" ["-g"]="arg_no_wifi_mac_address_found NEXT" ["--no-wifi-mac-address-found"]="arg_no_wifi_mac_address_found NEXT" ["--username"]="arg_username ANY" ["-u"]="arg_username ANY" ["--password"]="arg_password ANY" ["-p"]="arg_password ANY" ["--check-rfkill"]="arg_check_rfkill NEXT" ["-r"]="arg_check_rfkill NEXT" ["--use-iplink-if-available"]="arg_use_iplink_if_available NEXT" ["-u"]="arg_use_iplink_if_available NEXT" )

#This section of the program reads the flags provided when the program was launched
c=$#
while [ "$c" -gt 0 ]; do
	if ! partof "$1" "-m --mac"; then
		if [ -n "${valid[$1]}" ]; then
			to_assign=$(echo "${valid[$1]}"| cut -d' ' -f 1)
			value=$(echo "${valid[$1]}" | cut -d' ' -f 2)
			if [ "$value" == "NEXT" ]; then
				((c=c-1))
				firstloop=true
				list_values=""
				for i in ${possiblearguments["$to_assign"]}; do
					if [ "$firstloop" == true ]; then
						list_values="$i"
						firstloop=false
						continue
					fi
					list_values="$list_values, $i"
				done
				unset firstloop
				if [ "$c" -le 0 ]; then
					echo "Flag '$1' requires an argument : the possible values are : $list_values.">&2
					exit 2
				fi
				currentflag="$1"
				shift
				if ! partof "$1" "${possiblearguments["$to_assign"]}"; then
					echo "Argument '$1' of flag '$currentflag' invalid : the possible values are : $list_values.">&2
					exit 2
				fi
				args["$to_assign"]="$1"
				unset list_values
				unset currentflag
			elif [ "$value" == "ANY" ]; then
				((c=c-1))
				if [ "$c" -le 0 ]; then
					echo "Flag '$1' requires an argument !">&2
					exit 2
				fi
				shift
				args["$to_assign"]="$1"
			else
				args["$to_assign"]="$value"
			fi
		else
			echo "Failed to recognize flag '$1' : you can run \"$0 --help\" to get a list of flags">&2
			exit 2
		fi
	else
		((c=c-1)) #Parce que askip c=$(expr "$c" - 1) ne devrait plus être utilisé depuis au moins 20 ans.
		if [ "$c" -le 0 ]; then
			echo "Flag '$1' requires a mac address, or any of : prompt, promptifmultiple, all">&2
			exit 2
		fi
		currentflag="$1"
		shift
		if partof "$1" "prompt promptifmultiple all"; then
			args["arg_mac"]="$1"
		else
			#on vérifie que l'on a bien une adresse mac (qlq chose de la forme AA:BB:CC:DD:EE:FF)
			mac="$1"
			mac=$(echo "$mac" | tr "abcdef-" "ABCDEF:" | tr -d ' ')
			index=1
			finalmac=''
			while [ "$index" -le 6 ]; do
				i=$(echo "$mac" | cut -d':' -f "$index")
				firstchar=$(echo "$i" | cut -b 1)
				secondchar=$(echo "$i" | cut -b 2)
				thirdchar=$(echo "$i" | cut -b 3)
				validcharacters="0 1 2 3 4 5 6 7 8 9 A B C D E F"
				if ([ -z "$i" ] || [ -n "$thirdchar" ] || ( ! partof "$firstchar" "$validcharacters" ) || ( ! partof "$secondchar" "$validcharacters")); then
					echo "Failed to recognize argument '$1' : the $currentflag flag needs to be followed by a mac address, prompt, promptifmultiple, all !" >&2
					exit 2
				fi
				finalmac="$finalmac:$firstchar$secondchar"
				if [ "$index" -eq 1 ]; then
					finalmac=$(echo "$finalmac" | tr -d ':')
				fi
				((index=index+1))
			done
			i=$(echo "$mac" | cut -d':' -f 7)
			if [ -n "$i" ]; then
				echo "Failed to recognize argument '$1' : the --mac flag needs to be followed by a mac address !" >&2
				exit 2
			fi
			if partof "$finalmac" 'FF:FF:FF:FF:FF:FF 00:00:00:00:00:00'; then
				echo "Failed to recognize argument '$1' : '00:00:00:00:00:00' and 'FF:FF:FF:FF:FF:FF' are special addresses and most likely not your actual mac address">&2
				exit 2
			fi
			unset i
			unset index
			unset mac
			args["arg_mac"]="$finalmac"
			unset finalmac
		fi	
	fi
	((c=c-1))
	shift
done

VERSION="0.0.2"
#Shows documentation if needed
if [ "${args[arg_help]}" == yes ]; then
	echo "Script : $0 $VERSION"
	echo "This script will allow you (assuming you have already paid, and assuming you have already specified the wired and wireless mac addresses of your computer on adh6.minet.net) to set up the connection."
	echo 'A specific configuration of the connection needs to be done because the MiNET connection is considered to be an "enterprise connection" with a security level that allows for authentication.'
	echo ""
	echo "Here is a list of flags (in case of a conflict between flags, the last one prevails) :"
	echo ""
	echo "-h --help"
	echo "	This flag will show you this text message, and leave."
	echo "	Disabled by default."
	echo ""
	echo "-v --verbose"
	echo "	This flag will show debug information, that could help somebody figure out why something went wrong."
	echo "	Disabled by default."
	echo ""
	echo "-V --version"
	echo "	This flag will print the version of the program, and leave."
	echo "	Disabled by default."
	echo ""
	echo "-l --language en/fr/prompt"
	echo "	This flag will allow the user to choose between the two languages of this program."
	echo "	This choice will not affect this help section, or the --verbose flag."
	echo "	By default, set to 'prompt' : the user will get to interactively choose their language."
	echo ""
	echo "-t --type ethernet/wifi/both/prompt"
	echo "	This flag will allow the user to choose whether they want to setup a wired connection, a wireless connection, or both."
	echo "	By default, set to 'prompt' : the user will get to interactively choose."
	echo ""
	echo "-e --on-existing abort/delete/prompt"
	echo "	This flag will allow the user to choose what to do in case a connection to the MiNET network has already been configured."
	echo "	By default, set to 'prompt' : the user will get to interactively choose whether to delete that connection or leave the program."
	echo ""
	echo "-r --check-rfkill yes/no"
	echo "	This flag will allow the user to choose whether they want to check if their card is rfkilled or not."
	echo "	By default, set to 'yes'."
	echo ""
	echo "-c --check-for-wifi-mac-address"
	echo "	This flag will allow the user to specify that they want the program to check if they have a wireless card that is being detected by the system."
	echo "	There is no equivalent to this flag for ethernet connections, because nmcli requires that a mac address gets specified when a wired connection gets configured, meaning it would be impossible to create an ethernet connection without a wired mac address, and that the program checks for an ethernet mac address when necessary."
	echo "	By default, this flag is implied if and only if the type is 'wifi' or 'both'."
	echo ""
	echo "-C --dont-check-for-wifi-mac-address"
	echo "	The exact opposite of the previous flag."
	echo ""
	echo "-g --no-wifi-mac-address-found abort/warn"
	echo "	This flag is only considered if the --check-for-wifi-mac-address flag is set, and decides what to do if no wifi mac address has been found."
	echo "	By default, set to 'abort'"
	echo ""
	echo "-u --use-iplink-if-available yes/no"
	echo "	This flag decides whether to use the ip link command if it exists on your computer, to complement the use of nmcli to find wifi mac addresses. It can be used to fix a bug where the wrong mac address is displayed for wifi cards if you are in a 'not connected' state. This flag doesn't disable searching for wifi mac adresses, but it disables it being prompted to the user."
	echo ""
	echo "-m --mac <AA:BB:CC:DD:EE:FF>/prompt/promptifmultiple/all"
	echo "	This flag decides which mac address will be used to create a *wired* connection."
	echo "	This flag won't matter if the user isn't looking to create a wired connection."
	echo "	If set to prompt, the program will look for available mac addresses in your system and ask you to choose one. If no wired mac address is found, the program halts."
	echo "	If set to promptifmultiple, the program will look for available mac addresses in your system and ask you to choose one if there's more than one, otherwise choose the only one that exists. If no wired mac address is found, the program halts."
	echo "	If set to all, the program will look for available mac addresses in your system and create as many wired connections using the given username and password as there are wired mac addresses. If no mac address is found, the program keeps going."
	echo "	If set to a wired mac address, the program will skip checking for available mac addresses and use the one provided instead. Only one mac address can be provided using this method."
	echo "	By default, set to 'promptifmultiple'."
	echo ""
	echo "-u --username <USERNAME>"
	echo "	This flag allows the user to specify their adh6 (MiNET) username."
	echo "	If not set, the user will get interactively prompted for their username."
	echo "	WARNING : Avoid using this flag, as characters could be misinterpreted by bash when specifying the username if not enclosed by appropriate string delimiters."
	echo ""
	echo "-p --password <PASSWORD>"
	echo "	This flag allows the user to specify their adh6 (MiNET) password."
	echo "	If not set, the user will get interactively prompted for their password."
	echo "	WARNING : Avoid using this flag, as characters could be misinterpreted by bash when specifying the password if not enclosed by appropriate string delimiters."
	echo "	WARNING : Avoid using this flag, because your password will be written in your command history ! And if this program were to fail, and you needed help, you could accidentally show your password to the people helping you ! (MiNET doesn't know and will never need to know your password !)"
	echo ""
	exit 0
fi

#Shows version if needed
if [ "${args[arg_version]}" == yes ]; then
	echo "autoConnectLinuxMiNET.sh version $VERSION"
	exit 0
fi
unset VERSION

#Chooses whether to show debug messages
if [ "${args[arg_verbose]}" == yes ]; then
	exec 3>/dev/stdout
	#echo "..." >&3 will be seen on the command line
else
	exec 3>/dev/null
	#echo "..." >&3 won't be seen on the command line
fi

#Allows the user to choose their language if needed
if [ "${args[arg_language]}" == prompt ]; then	
	echo "1) FR"
	echo "2) EN"
	echo "3) Quit program"
	echo "Choose language (1/2/3) : "
	validfr="1 1) FR fr Fr French french Français Francais français francais FRANCAIS"
	validen="2 2) EN en En English english ENGLISH"
	validq="3 3) q Q quit Quit leave Leave exit Exit QUIT LEAVE EXIT"
	validlang="$validfr $validen $validq"
	read -r lang
	until partof "$lang" "$validlang"; do
		echo "Choose language (1/2/3)"
		read -r lang
	done

	if partof "$lang" "$validfr"; then
		args["arg_language"]=fr
	elif partof "$lang" "$validen"; then
		args["arg_language"]=en
	else
		echo "Aborted by user.">&2
		exit 3
	fi
	unset lang
fi
echo "[DEBUG] Chosen language : ${args['arg_language']}">&3

#Checks if the card isn't rfkilled
echo "[DEBUG] Chosen whether to check for rfkilled cards : ${args['arg_check_rfkill']}" >&3
if [ "${args['arg_check_rfkill']}" == "yes" ]; then
	rfkill --help 1>/dev/null 2>/dev/null
	diditwork="$?"
	if [ "$diditwork" -eq 0 ]; then
		if partof "blocked" "$(rfkill --output HARD)"; then
			echolang "${args[arg_language]}" "[WARNING] rfkill indicates that one of your cards is hardware-blocked ! If this is the card you wish to use, then the connection will not work until unblocked. If you believe this is normal, press Enter to continue." "[WARNING] rfkill affiche que l'une de vos cartes est bloquée au niveau hardware ! S'il s'agit de la carte que vous voulez utiliser, alors la connection ne vas pas fonctionner jusqu'à ce qu'elle soit débloquée. Si vous pensez que c'est normal, appuyez sur Entrée pour continuer."
			read -r
		fi
		if partof "blocked" "$(rfkill --output SOFT)"; then
			echolang "${args[arg_language]}" "[WARNING] rfkill indicates that one of your cards is software-blocked ! If this is the card you wish to use, then the connection will not work until unblocked (You can try to use 'rfkill unblock all'). If you believe this is normal, press Enter to proceed." "[WARNING] rfkill affiche que l'une de vos cartes est bloquée au niveau software ! S'il s'agit de la carte que vous voulez utiliser, alors la connection ne vas pas fonctionner jusqu'à ce qu'elle soit débloquée (Vous pouvez commencer par essayer 'rfkill unblock all'). Si vous pensez que c'est normal, appuyez sur Entrée pour continuer"
			read -r
		fi
	fi
	unset diditwork
fi

#Allows the user to choose the connection type if needed
if [ "${args[arg_type]}" == prompt ]; then
	echo "1) wifi"
	echo "2) ethernet"
	echolang "${args[arg_language]}" "3) both" "3) les deux"
	echolang "${args[arg_language]}" "4) Quit program" "4) quitter le programme"
	echolang "${args[arg_language]}" "Choose (1/2/3) : " "Choisissez (1/2/3) : "
	read -r chosen_type
	validwifi="1 1) wifi Wifi WiFi WIFI"
	validethernet="2 2) ethernet Ethernet ETHERNET"
	validboth="3 3) both Both BOTH"
	if partof "$chosen_type" "$validwifi"; then
		args["arg_type"]=wifi
	elif partof "$chosen_type" "$validethernet"; then
		args["arg_type"]=ethernet
	elif ( partof "$chosen_type" "$validboth" || [ "$chosen_type" == "Les deux" ] || [ "$chosen_type" == "les deux" ] || [ "$chosen_type" == "Les Deux" ] || [ "$chosen_type" == "LES DEUX" ] ); then
		args["arg_type"]=both
	else
		echolang "${args[arg_language]}" "Aborted by user." "Programme quitté par l'utilisateur.">&2
		exit 3
	fi
	unset chosen_type
fi
echo "[DEBUG] Chosen type : ${args['arg_type']}" >&3

if [ "${args[arg_check_for_wifi_mac_address]}" == undecided ]; then
	if partof "${args[arg_type]}" "wifi both"; then
		args[arg_check_for_wifi_mac_address]=yes
	elif [ "${args[arg_type]}" == "ethernet" ]; then
		args[arg_check_for_wifi_mac_address]=no
	else
		echo "Could not determine type (both, wifi, ethernet). This is a critical bug and should be reported.">&2
		exit 1
	fi
fi
echo "[DEBUG] Check for wifi mac address : ${args['arg_check_for_wifi_mac_address']}" >&3

#The program checks for available mac addresses depending on flags (only using nmcli!)
#Then chooses which mac address will be kept
if ( [ "${args[arg_check_for_wifi_mac_address]}" == yes ] || partof "${args[arg_type]}" "ethernet both" ); then
	echo "[DEBUG] Detecting mac addresses" >&3
	echo "[DEBUG] No wifi mac address found : ${args[arg_no_wifi_mac_address_found]}" >&3
	echo "[DEBUG] mac address to consider : ${args[arg_mac]}" >&3
	
	mac_ethernet=""
	nb_ethernet=0
	mac_wifi=""
	nb_wifi=0
	echo "[DEBUG] iplink is present : $iplink_is_present" >&3
	echo "[DEBUG] use ip link if available : ${args[arg_use_iplink_if_available]}" >&3
	for i in $(nmcli dev show | grep GENERAL.DEVICE | tr -d ' ' | cut -d':' -f 2); do
		card_type=$(nmcli dev show "$i" | grep GENERAL.TYPE | tr -d ' ' | cut -d':' -f 2)
		mac=$(nmcli dev show "$i" | grep GENERAL.HWADDR | tr -d ' ' | cut -d':' -f 2-7)
		if [ "$iplink_is_present" == "true" ] && [ "${args[arg_use_iplink_if_available]}" == "yes" ] && [ "$card_type" == "wifi" ]; then
			iplinkresult=$(ip link show "$i" | tr " " "@" )
			for line in $iplinkresult; do
				line=$(echo "$line" | tr "@" " ")
				newline=""
				for word in $line; do
					if [ -z "$newline" ]; then
						newline="$word"
					else
						newline="$newline $word"
					fi
				done
				unset word
				line=$(echo "$newline" | grep link)
				unset newline
				if [ -n "$line" ]; then
					next_is_mac="false"
					permaddr="false"
					for word in $line; do
						if [ "$next_is_mac" == "true" ]; then
							iplink_mac=$(echo "$word" | tr 'abcdef' 'ABCDEF')
							next_is_mac="false"
						fi
						if echo "$word" | grep -q "link"; then
							if [ "$permaddr" == "false" ]; then
								next_is_mac="true"
							fi
						fi
						if echo "$word" | grep -q "permaddr"; then
							next_is_mac="true"
							permaddr="true"
						fi
					done
					unset word
					unset next_is_mac
					unset permaddr
				fi
			done
			unset line
			iplink_mac_duplicate="$iplink_mac" #qqlq tests pour être sûr que c'est une adresse mac
			if [ $(echo "$iplink_mac_duplicate" | tr -d " " | wc -c) -eq 18 ]; then #car inclut le \n de echo
				if [ -z "$(echo "$iplink_mac_duplicate" | tr -d "ABCDEF0123456789:")" ]; then
					if [ "$iplink_mac" != "$mac" ]; then
						echo "[WARNING] ip link shows a different mac address from nmcli ! ($iplink_mac instead of $mac)" >&3
						mac=$iplink_mac
					fi
				fi
			fi
		fi

		if [ "$card_type" == "ethernet" ]; then
			if [ -z "$mac_ethernet" ]; then
				mac_ethernet="$mac"
			else
				mac_ethernet="$mac_ethernet $mac"
			fi
			((nb_ethernet = nb_ethernet+1))
		elif [ "$card_type" == "wifi" ]; then
			if [ -z "$mac_wifi" ]; then
				mac_wifi="$mac"
			else
				mac_wifi="$mac_wifi $mac"
			fi
			((nb_wifi = nb_wifi+1))
		fi
		echo "[DEBUG] Found card $mac of type $card_type" >&3

	done
		

	echo "[DEBUG] nb_ethernet found : $nb_ethernet" >&3
	echo "[DEBUG] list of ethernet mac addresses $mac_ethernet" >&3
	echo "[DEBUG] nb_wifi found : $nb_wifi" >&3
	echo "[DEBUG] list of wifi mac addresses $mac_wifi" >&3
	if ( [ "${args[arg_check_for_wifi_mac_address]}" == yes ] && [ "$nb_wifi" -eq 0 ] ); then
		if [ "${args[arg_no_wifi_mac_address_found]}" == warn ]; then
			echolang "${args[arg_language]}" "WARNING : No WiFi mac address was found !" "Attention ! Aucune adresse mac correspondant à une carte WiFi n'a été trouvée !"
		elif [ "${args[arg_no_wifi_mac_address_found]}" == abort ]; then
			echolang "${args[arg_language]}" "ERROR : No WiFi mac address found ! Incompatible options. Run $0 --help for help." "Attention ! Aucune adresse mac correspondant à une carte WiFi n'a été trouvée ! $0 --help pour de l'aide." >&2
			exit 1
		fi
	fi

	if partof "${args[arg_type]}" "ethernet both"; then
		if [ "${args[arg_mac]}" == prompt ] || ( [ "${args[arg_mac]}" == promptifmultiple ] && [ "$nb_ethernet" -gt 1 ] ); then
			c=1
			for i in $mac_ethernet; do
				echo "$c) $i"
				((c=c+1))
			done
			echolang "${args[arg_language]}" "Enter a number, 0 to exit" "Entrez un nombre, 0 pour quitter"
			read -r choice
			while ( [[ -n $(echo "$choice" | tr -d "0123456789") ]] || [ "$choice" -ge "$c" ] ); do
				echolang "${args[arg_language]}" "This is not a number < $c ! Type 0 to exit" "Ce n'est pas un nombre < $c ! Tapez 0 pour quitter"
				read -r choice
			done
			if [ "$choice" -eq 0 ]; then
				echolang "${args[arg_language]}" "Aborted by user." "Programme quitté par l'utilisateur.">&2
				exit 3
			fi
			c=1
			for i in $mac_ethernet; do
				if [ "$c" -eq "$choice" ]; then
					args[arg_mac]="$i"
				fi
				((c=c+1))
			done
			unset choice
		elif ( [ "${args[arg_mac]}" == all ] || ( [ "${args[arg_mac]}" == promptifmultiple ] && [ "$nb_ethernet" -eq 1 ] ) )  ; then
			args[arg_mac]="$mac_ethernet"
		elif ( [ "$nb_ethernet" -eq 0 ] && partof "${args[arg_mac]}" "prompt promptifmultiple all" ); then 
			echolang "${args[arg_language]}" "No ethernet mac address found ! To provide one manually, run : $0 --mac AA:BB:CC:DD:EE:FF. For help, run : $0 --help" "Pas d'addresse mac ethernet trouvée ! Pour en assigner une manuellement, lancez : $0 --mac AA:BB:CC:DD:EE:FF. Pour de l'aide, lancez : $0 --help" >&3
			exit 1
		fi
	fi
fi
echo "[DEBUG] Chosen mac addresse(s) : ${args[arg_mac]}" >&3

#The program checks for existing connections to the MiNET network, and prompts the user if needed
p=$(nmcli con show | tr '\n' '@')
c=2
line="notempty"
to_delete=""
while true; do
	line=$( echo $p | cut -d'@' -f "$c" )
	if [ -z "$line" ]; then
		break
	fi
	nbwords=0
	for i in $line; do
		((nbwords=nbwords+1))
	done
	connection_uuid=$( echo "$line" | cut -d' ' -f "$(expr $nbwords - 2 )" )
	hasMiNET=$(nmcli connection show "$connection_uuid" | grep "MiNET")
	if [ -n "$hasMiNET" ] ; then
		connection_name=$( echo "$line" | cut -d' ' -f -"$(expr $nbwords - 3)" )
		connection_type=$( nmcli connection show "$connection_uuid" | grep connection.type | cut -d':' -f 2 )
		is_ethernet=$( echo $connection_type | grep ethernet ) #pas de "" volontairement !
		is_wireless=$( echo $connection_type | grep wireless ) #pas de "" volontairement !
		if [ -n "$is_ethernet" ]; then
			connection_type="ethernet"
		elif [ -n "$is_wireless" ]; then
			connection_type="wifi"
		fi
		if ( ( [ -n "$is_ethernet" ] && ( partof "${args[arg_type]}" "ethernet both" ) ) || ( [ -n "$is_wireless" ] && ( partof "${args[arg_type]}" "wifi both" ) ) ); then
			if [ "${args[arg_on_existing]}" == prompt ]; then
				echolang "${args[arg_language]}" "Connection '$connection_name' of type '$connection_type' seems to already be configured for MiNET ! Delete it and proceed ? y/n" "La connection '$connection_name' de type '$connection_type' semble déjà être configurée pour MiNET ! La supprimer et continuer ? o/n"
				read -r answer
				if partof "$answer" "y yes Yes YES o oui Oui OUI"; then
					to_delete="$to_delete $connection_uuid"
				else
					echolang "${args[arg_language]}" "Aborted by user." "Programme quitté par l'utilisateur.">&2
					exit 3
				fi
			elif [ "${args[arg_on_existing]}" == delete ]; then
				to_delete="$to_delete $connection_uuid"
			else
				echolang "${args[arg_language]}" "Connection '$connection_name' of type '$connection_type' already configured for MiNET. Exiting." "Connection '$connection_name' de type '$connection_type' déjà configurée pour MiNET. Fin du programme.">&2
				exit 1
			fi	
		fi
	fi
	unset connection_uuid
	unset hasMiNET
	unset nbwords
	line=""
	((c=c+1))
done

#The program actually deletes the other connections
for connection_uuid in $to_delete; do
	nmcli connection delete "$connection_uuid" >/dev/null
	echo "[DEBUG] Connection ID '$connection_uuid' deleted." >&3
done

#The program promps the user for their username, if needed
if [ -z "${args[arg_username]}" ]; then
	echolang "${args[arg_language]}" "Please specify your adh6 (MiNET) username : " "Ecrivez votre pseudo adh6 (MiNET) : "
	read -r username
	args[arg_username]="$username"
fi
echo "[DEBUG] Chosen username : ${args[arg_username]}">&3

#The program prompts the user for their password, if needed
if [ -z "${args[arg_password]}" ]; then
	echolang "${args[arg_language]}" "Please specify your adh6 (MiNET) password (it will not show, that's intentional) : " "Ecrivez votre mot de passe adh6 (MiNET) (c'est normal qu'il n'apparaisse pas à l'écran) : "
	read -s -r password
	echolang "${args[arg_language]}" "If you realize you mistyped your username or password, rerun this program to overwrite the previous configuration." "Si vous réalisez que vous avez mal tapé votre pseudo ou mot de passe, relancez ce programme pour écraser l'ancienne configuration"
	args[arg_password]="$password"
fi
echo "[DEBUG] The password has been chosen." >&3

#The program creates a wireless connection, if needed
if partof "${args[arg_type]}" "wifi both"; then
	nmcli con add type wifi con-name MiNETAuto ssid "MiNET" connection.autoconnect-priority 2 wifi-sec.key-mgmt wpa-eap 802-1x.domain-suffix-match minet.net 802-1x.eap peap 802-1x.identity "${args[arg_username]}" 802-1x.password "${args[arg_password]}" 802-1x.phase2-auth mschapv2 >/dev/null
	nmcli con add type wifi con-name MiNETAuto24 ssid "MiNET_2.4" connection.autoconnect-priority 1 wifi-sec.key-mgmt wpa-eap 802-1x.domain-suffix-match minet.net 802-1x.eap peap 802-1x.identity "${args[arg_username]}" 802-1x.password "${args[arg_password]}" 802-1x.phase2-auth mschapv2 >/dev/null
	echo "[DEBUG] Added wireless (MiNET and MiNET_2.4) connections for username '${args[arg_username]}'" >&3
	for mac in $mac_wifi; do
		if [ "$iplink_is_present" == "true" ] && [ "${args[arg_use_iplink_if_available]}" == "yes" ]; then
			echolang "${args[arg_language]}" "Don't forget to add wireless mac address '$mac' on adh6.minet.net, otherwise the newly-created configuration won't work !" "N'oubliez pas d'ajouter l'adresse mac '$mac' en tant qu'adresse wifi sur adh6.minet.net, sinon cette configuration ne pourra pas fonctionner !"
		else
			echolang "${args[arg_language]}" "Don't forget to add your wireless mac address on adh6.minet.net (run ip link to find it)" "N'oubliez pas d'ajouter votre adresse mac wifi sur adh6.minet.net (lancez ip link pour la voir)"
		fi
	done	
fi

#The program creates as many wired connections as needed
if partof "${args[arg_type]}" "ethernet both"; then
	for mac in ${args[arg_mac]}; do
		nmcli con add type ethernet con-name MiNETAutoFil mac "$mac" ethernet.auto-negotiate true 802-1x.eap peap 802-1x.identity "${args[arg_username]}" 802-1x.password "${args[arg_password]}" 802-1x.phase2-auth mschapv2 ipv6.addr-gen-mode eui64 >/dev/null
		echo "[DEBUG] Added ethernet connection for mac '$mac' and username '${args[arg_username]}'" >&3
		echolang "${args[arg_language]}" "Don't forget to add wired mac address '$mac' on adh6.minet.net, otherwise the newly-created configuration won't work !" "N'oubliez pas d'ajouter l'addresse mac '$mac' en tant qu'adresse filaire sur adh6.minet.net, sinon cette configuration ne pourra pas fonctionner !" 
	done
fi

