#!/bin/bash
# lastact: arturo@2023-05-03
# desc: Script de configuración automática de las Wireless de los centros Vitalinux

# 0) Importamos las funciones de bash:
FICHFUNCS="/usr/bin/vx-funcs-bash"
[ -f "${FICHFUNCS}" ] && . "${FICHFUNCS}" "null"

# 1) Comprobamos que es el usuario root quien quiere ejecutar el programa, sino salimos:
vx-check_user_root "Debes acceder con privilegios de root para configurar la Wireless"

MOSTRARMENSAJE=1
DEBUG=false

# 2) Comprobamos que hay una interfaz wireless disponible para seguir. En caso contrario esperamos 5 minutos a detectar una:
NINTENTOS=1
while true; do
    # Listamos la lista de interfaces wireless para saber si hay alguna conectada:
    "${DEBUG}" &&
        echo "=> Estado de las interfaces de red:" &&
        nmcli -t -f device,type,state dev status
    ## wlan0:802-11-wireless:desconectado | wlo1:wifi:connected | p2p-dev-wlo1:wifi-p2p:disconnected
    ## eth0:802-3-ethernet:no disponible | enp8s0:ethernet:unavailable
    ## wlan1:802-11-wireless:conectado
    ## lo:loopback:unmanaged
    # Para comprobar si disponemos de una interfaza wireless: # Otra opción: nmcli -t -f ssid dev wifi list
    # Comprobamos el número de interfaz wireless del equipo: (la opción -c del grep evita poner wc -l)
    # NDEVICESWIRELESS="$(nmcli -t -f type,state dev status | grep -c "^802-11-wireless:\|^wifi:")"
    DEVICESWIRELESS=($(nmcli -t -f device,type,state dev status | grep -E ":802-11-wireless:|:wifi:"))
    if (("${#DEVICESWIRELESS[@]}" == 0)); then
        ((NINTENTOS == 1)) || "${DEBUG}" && echo "=> $(date) - No se detecta ninguna interfaz Wireless que configurar. Lo intentaremos durante 5 minutos"
        ((NINTENTOS++))
        if ((NINTENTOS == 30)); then
            echo "=> $(date) - Salimos. No hay ninguna interfaz Wireless que configurar"
            exit 0
        fi
        sleep 10
    else
        echo "=> Se han localizado ${#DEVICESWIRELESS[@]} interfaces wireless: ${DEVICESWIRELESS[*]%%:*}"
        break
    fi
done

# 3) Preparamos la auditoria:
LOG="$(basename "${0}").log"
vx-log_xsession -o "${LOG}"

TEXTO="Configuración de las Redes Wireless de los centros Vitalinux - Interfaces: ${DEVICESWIRELESS[*]%%:*}"
vx-echo_log_titulo1 "SRV-CONF-WIRELESS" "${TEXTO}"

# Cargamos el JSON de redes Wireless de los centros educativos:
WIRELESSCENTROS="/usr/share/vitalinux/wireless/.vx-wireless-centros.json"
[[ ! -f "${WIRELESSCENTROS}" ]] && echo "=> No hay wifis de centros" && exit 1
WIRELESS_JSON="$(<"${WIRELESSCENTROS}")" # Cargamos el archivo en una variable
WIRELESSLISTADO="/usr/share/vitalinux/wireless/vx-listado-redes-wireless-disponibles"

# 4) En el caso de disponer de una interfaz Wireless trateremos de conectarnos a una Wifi del listado: 5 intentos
NINTENTOS=0
while ((NINTENTOS < 5)); do
    # Para saber si ya hay una conexión wireless ya establecida se puede hacer de dos formas:
    ## 1) nmcli -t -f devices,name con status : Nos devuelve únicamente las conexiones activas (necesitamos saber el nombre de la interfaz Wireless en el sistema para filtrarlo)
    # for DEVICEWIRELESS in $(nmcli -t -f device,type dev status | grep -E "wireless|wifi" | cut -d":" -f1); do
    for DEVICEWIRELESS in "${DEVICESWIRELESS[@]%%:*}"; do
        "${DEBUG}" && echo "#> Interfaz de red wireless disponible: ${DEVICEWIRELESS}"
        # DEVICEWIRELESS="$(nmcli -t -f device,type dev status  | grep -E "wireless|wifi" | cut -d":" -f1 | head -1)"
        REDWIRELESSCONECTADO="$(nmcli -t -f DEVICE,NAME con show --active |
            grep "${DEVICEWIRELESS}:" | cut -d':' -f2)"

        ## 2) nmcli -t -f type,state dev status : el parámetro "state" nos dice si esta conectado|desconectado
        if [[ "${REDWIRELESSCONECTADO}" ]]; then
            CONFWIRELESS_UUID="$(nmcli -t -f DEVICE,UUID con show --active | grep "^${DEVICEWIRELESS}:" | cut -d":" -f2)"
            RUTAFICHERO="$(grep -R "^uuid=${CONFWIRELESS_UUID}" "/etc/NetworkManager/system-connections" | cut -d":" -f1)"
            [[ "${RUTAFICHERO}" ]] && FICHCONFREDACTIVO="$(basename "${RUTAFICHERO}")" || FICHCONFREDACTIVO="Ninguno"

            NOMBRERED="$(grep "ssid" "/etc/NetworkManager/system-connections/${FICHCONFREDACTIVO}" | cut -d"=" -f2)"
            # Mostramos una vez el mensaje de conexión a la wireless (variable MOSTRARMENSAJE):

            MENSAJE="Estas conectado actualmente a la Wireless: \"${NOMBRERED}\""
            (("${MOSTRARMENSAJE}" == 1)) &&
                echo "#> ${MENSAJE}. No es necesario configurar nada." &&
                notify-send \
                    "Wireless Vitalinux" "${MENSAJE}" \
                    -i wireless -t 5000 &&
                MOSTRARMENSAJE=0

            #exit 0
        else
            WIRELESSVX="0"

            # Obtenemos una lista de las redes disponibles en el entorno, las ordenamos por signal, eliminando redes sin determinar, y repeticiones:
            # sed "/::/d" => Eliminamos redes detectadas pero no identificadas
            # awk '!x[$0]++' => Elimina las repeticiones, al no almacenar en el array elementos que ya existan
            nmcli -t -f signal,ssid device wifi list |
                sort -r | grep -E "^[0-9]" | awk -F ":" '{ print ":"$2":" }' | sed "/::/d" | awk '!x[$0]++' >"${WIRELESSLISTADO}"

            CONTADOR=1
            NREDES=$(wc -l <"${WIRELESSLISTADO}")
            while [ "${CONTADOR}" -le "${NREDES}" ]; do

                REDWIRELESS="$(head -${CONTADOR} "${WIRELESSLISTADO}" | tail -1 | cut -d":" -f2)"
                # if awk -F ":" '{ print $1 ":" $3 ":" }' "${WIRELESSCENTROS}" | grep -q "${REDWIRELESS}"; then # Con fichero CSV
                OLDIFS=$IFS # Modificamos IFS para crear un Array a partir del número de redes encontradas con ese nombre
                IFS=$'\n'
                "${DEBUG}" && vx-colorear_echo "azul" "#> Probamos si tenemos datos de la Wifi: ${REDWIRELESS}"
                DATOS_WIRELESS=($(jq --arg REDWIRELESS "${REDWIRELESS}" -c '.wireless[] | select(.ssid | contains($REDWIRELESS))' <<<"${WIRELESS_JSON}"))
                for DATOS_WIFI in "${DATOS_WIRELESS[@]}"; do
                    "${DEBUG}" && echo "#> Datos Wifi ${REDWIRELESS}: ${DATOS_WIFI}"
                    # # Buscamos una red cuyo parámetro ssid sea “Adultos”:
                    # RED="$(jq -c '.wireless[] | select(.ssid | contains("Adultos"))' <<<$JSON)"
                    # # Extraemos la password:
                    # PASS="$(jq ".password" <<<$RED)"

                    WIRELESSVX="1"
                    # En el caso de encontrar dos líneas con el mismo nombre de red, cogemos la primera:
                    # NUMERO=$(awk -F ":" '{ print $1 ":" $3 ":" }' "${WIRELESSCENTROS}" | grep "${REDWIRELESS}" |
                    #     awk -F ":" '{ print $1 }' | head -1)

                    # IDRED="$(grep "^${NUMERO}:" "${WIRELESSCENTROS}" | cut -d':' -f2)"
                    # NOMBRERED="$(grep "^${NUMERO}:" "${WIRELESSCENTROS}" | cut -d':' -f3)"
                    # PASSWORD="$(grep "^${NUMERO}:" "${WIRELESSCENTROS}" | cut -d':' -f4)"
                    IDRED="$(jq -r ".nombre" <<<"${DATOS_WIFI}")"
                    NOMBRERED="$(jq -r ".ssid" <<<"${DATOS_WIFI}")"
                    PASSWORD="$(jq -r ".password" <<<"${DATOS_WIFI}")"

                    # Comprobamos las restricciones de conexión al usuario que ha iniciado sesión:
                    USUGRAFICO="$(vx-usuario-grafico)"
                    # 1) Comprobamos la lista de usuarios sin permiso de acceso: sexto campo del fichero
                    # USUS_SIN_PERMISO="$(grep "^${NUMERO}:" "${WIRELESSCENTROS}" | cut -d':' -f6)"
                    USUS_SIN_PERMISO="$(jq -r ".users_deny" <<<"${DATOS_WIFI}")"
                    [[ -z "${USUS_SIN_PERMISO}" ]] && USUS_SIN_PERMISO="none"
                    [[ ";${USUS_SIN_PERMISO};" =~ \;${USUGRAFICO}\; ]] &&
                        {
                            ((CONTADOR++))
                            continue
                        }
                    # 2) Comprobamos la lista de usuarios con permiso de acceso: septimo campo del fichero
                    # USUS_CON_PERMISO="$(grep "^${NUMERO}:" "${WIRELESSCENTROS}" | cut -d':' -f7)"
                    USUS_CON_PERMISO="$(jq -r ".users_allow" <<<"${DATOS_WIFI}")"
                    [[ -z "${USUS_CON_PERMISO}" ]] && USUS_CON_PERMISO="all"
                    [[ ! ";${USUS_CON_PERMISO};" =~ \;all\; ]] &&
                        [[ ! ";${USUS_CON_PERMISO};" =~ \;${USUGRAFICO}\; ]] &&
                        {
                            ((CONTADOR++))
                            continue
                        }

                    # Comprobamos que no existe ya una configuración existente de conexión a esa red wireless:
                    if ! (nmcli -t -f name,device con show --active | grep -E "^${IDRED}|^${NOMBRERED}" &>/dev/null); then
                        ##if ! test -f "/etc/NetworkManager/system-connections/${IDRED}" ; then
                        ##if ! ( grep "ssid=${NOMBRERED}" /etc/NetworkManager/system-connections/* &> /dev/null ) ; then
                        vx-colorear_echo "azul" "#> [$(vx-fecha)] - Se va a tratar de configurar la red wireless: ${NOMBRERED}"
                        if ! test -z "${PASSWORD}"; then
                            if nmcli device wifi connect "${NOMBRERED}" password "${PASSWORD}" name "${IDRED}"; then
                                vx-colorear_echo "azul" "#> [$(vx-fecha)] - Se ha configurado la red wireless: ${NOMBRERED}"
                                notify-send \
                                    "Wireless Centros Vitalinux" "Se ha configurado la red wireless: \"${NOMBRERED}\"" \
                                    -i wireless -t 5000
                                exit 0
                            fi
                        else
                            if nmcli device wifi connect "${NOMBRERED}" name "${IDRED}"; then
                                vx-colorear_echo "azul" "#> [$(vx-fecha)] - Se ha configurado la red wireless: ${NOMBRERED}"
                                notify-send \
                                    "Wireless Centros Vitalinux" "Se ha configurado la red wireless: \"${NOMBRERED}\"" \
                                    -i wireless -t 5000
                                exit 0
                            fi
                        fi
                    fi

                done
                ((CONTADOR++))
            done
            #exit 0
        fi
    done
    ((NINTENTOS++))
    sleep 5
done
