#!/bin/bash
# version: arturo@2023-11-09, arturo@2019-12-12
# Parseamos el Json de configuración de centro y llamamos a los scripts correspondientes:

# Definimos una variable general a todo el script para indicar si queremos mostrar todo mensaje por la salida:
DEBUG=false

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

# Importamos el fichero de variables asociado a la configuración de centro:
FICH_VARS_CONF_CENTRO="/etc/default/vx-dga-variables/vx-dga-variables-conf-centro.conf"
[ -f "${FICH_VARS_CONF_CENTRO}" ] && . "${FICH_VARS_CONF_CENTRO}" "null"

FICHFUNCSUSERS="/usr/bin/vx-funcs-users"
[ -f "${FICHFUNCSUSERS}" ] && . "${FICHFUNCSUSERS}" "null"

USUGRAFICO="$(vx-usuario-grafico)"
GRUPOSUSUGRAFICO="$(id -Gn "${USUGRAFICO}")"

function vx-echo-titulo() {
    # Titulo con las siguientes características:
    # 1) En azul y negrita
    # 2) Titulo parpadeante
    # 3) Intertido el color y su background
    echo -e "\e[34m\e[1m\e[7m${1}\e[0m"
}

echo_azul="vx-colorear_echo_azul_negrita"
echo_rojo="vx-colorear_echo_rojo_negrita"
echo_verde="vx-colorear_echo_verde_negrita"
echo_titulo="vx-echo-titulo"

function mensaje() {
    "${echo_azul}" "=> $(date) - ${1}"
}

function check_cids_etiquetas_usuarios_grupos_proyecto() {
    NUMERO="${1}"
    CIDSCENTRO="${2}"
    # De las etiquetas del centro eliminamos el sufijo ";" del final para evitar errores:
    ETIQUETASCENTRO="${3%;}"
    EXCLUIDOS="${4%;}"
    DESC="${5:-"Parametro a configurar"}"
    ALLOW_USERS="${6:-"null"}"
    ALLOW_GROUPS="${7:-"null"}"
    DENY_USERS="${8:-"null"}"
    DENY_GROUPS="${9:-"null"}"
    PROYECTOS_INCLUIDOS="${10:-"null"}"
    FECHAINI="${11:-"null"}"
    FECHAFIN="${12:-"null"}"
    # Añadimos el Proyecto Migasfree al que pertenece el cliente migasfree:
    FICH_CONF_MIGASFREE="/etc/migasfree.conf"
    [[ -f "${FICH_CONF_MIGASFREE}" ]] &&
    PROYECTO="$(crudini --get "${FICH_CONF_MIGASFREE}" "client" "Project" 2> /dev/null || \
    crudini --get "${FICH_CONF_MIGASFREE}" "client" "Version" 2> /dev/null)" ||
    PROYECTO="null"
    
    # Tenemos en cuenta la igualdad de cuentas: alumno|estudiante, profesor|docente
    [[ ";${ALLOW_USERS};" =~ \;alumno|estudiante\; ]] &&
    ALLOW_USERS="alumno;estudiante;${ALLOW_USERS}"
    [[ ";${ALLOW_USERS};" =~ \;profesor|docente\; ]] &&
    ALLOW_USERS="profesor;docente;${ALLOW_USERS}"
    [[ ";${DENY_USERS};" =~ \;alumno|estudiante\; ]] &&
    DENY_USERS="alumno;estudiante;${DENY_USERS}"
    [[ ";${DENY_USERS};" =~ \;profesor|docente\; ]] &&
    DENY_USERS="profesor;docente;${DENY_USERS}"
    
    INFORMACION_SALIDA="=> ($(($NUMERO + 1))) {${DESC}} Chequeamos: CIDs, Etiquetas, excluidos ...
    ## CID: ${MIGASCID} # Proyecto: ${PROYECTO} # Etiquetas: $(echo ${ETIQUETAS} | tr -s '\n' ' ')"
    [[ "${CIDSCENTRO}" != "null" ]] && \
    INFORMACION_SALIDA+="\n    - CIDs-Centro donde aplicar: ${CIDSCENTRO}"
    [[ "${ETIQUETASCENTRO}" != "null" ]] &&
    INFORMACION_SALIDA+="\n    - Etiquetas-Centro donde aplicar: ${ETIQUETASCENTRO}"
    [[ "${EXCLUIDOS}" != "null" ]] &&
    INFORMACION_SALIDA+="\n    ## Equipos Excluidos: ${EXCLUIDOS}"
    [[ "${ALLOW_USERS}" != "null" || "${ALLOW_GROUPS}" != "null" || \
    "${DENY_USERS}" != "null" || "${DENY_GROUPS}" != "null" ]] &&
    INFORMACION_SALIDA+="\n    ## Usuario Gráfico: ${USUGRAFICO}
    - Usuarios|Grupos Permitidos: ${ALLOW_USERS//null/todos}|${ALLOW_GROUPS//null/todos}
    - Usuarios|Grupos Excluidos: ${DENY_USERS//null/ninguno}|${DENY_GROUPS//null/ninguno}"
    [[ "${PROYECTOS_INCLUIDOS}" != "null" ]] &&
    INFORMACION_SALIDA+="\n    ## Proyectos Incluidos: ${PROYECTOS_INCLUIDOS//null/todos}"
    [[ "${FECHAINI}" != "null" || "${FECHAFIN}" != "null" ]] &&
    INFORMACION_SALIDA+="\n    ## Fecha de Inicio: ${FECHAINI//null/cualquiera} | Fecha de Finalización: ${FECHAFIN//null/nunca}"
    
    # Chequeamos que el usuario gráfico esta incluido:
    if ! [[ "${ALLOW_USERS}" == "null" || \
            "${ALLOW_USERS}" == "all" || \
        ";${ALLOW_USERS};" =~ \;${USUGRAFICO}\; ]]; then
        "${DEBUG}" && "${echo_azul}" "${INFORMACION_SALIDA}" &&
        "${echo_rojo}" "=> El equipo esta excluido para este usuario gráfico (3) ..."
        return 1
    fi
    # Chequeamos si el usuario gráfico esta excluido:
    if [[ "${DENY_USERS}" != "null" && ";${DENY_USERS};" =~ \;${USUGRAFICO}\; ]] ||
    [[ "${DENY_USERS}" == "all" ]]; then
        "${DEBUG}" && "${echo_azul}" "${INFORMACION_SALIDA}" &&
        "${echo_rojo}" "=> El usuario gráfico esta excluido y no se realizará ninguna acción (5) ..."
        return 1
    fi
    # Chequeamos que alguno de los grupos del usuario gráfico esta incluido:
    if ! [[ "${ALLOW_GROUPS}" == "null" || \
        "${ALLOW_GROUPS}" == "all" ]]; then
        EXCLUIR="true"
        for GRUPO in ${GRUPOSUSUGRAFICO}; do
            [[ ";${ALLOW_GROUPS};" =~ \;${GRUPO}\; ]] && EXCLUIR="false"
        done
        if "${EXCLUIR}" ; then
            "${DEBUG}" && "${echo_azul}" "${INFORMACION_SALIDA}" && \
            "${echo_rojo}" "=> El equipo esta excluido por los grupos del usuario gráfico (4) ..."
            return 1
        fi
    fi
    # Chequeamos si alguno de los grupos del usuario gráfico esta excluido:
    EXCLUIR="false"
    [[ "${DENY_GROUPS}" == "all" ]] && EXCLUIR="true"
    if [[ "${DENY_GROUPS}" != "null" ]]; then
        for GRUPO in ${GRUPOSUSUGRAFICO}; do
            [[ ";${DENY_GROUPS};" =~ \;${GRUPO}\; ]] && EXCLUIR="true"
        done
    fi
    if "${EXCLUIR}"; then
        "${DEBUG}" && "${echo_azul}" "${INFORMACION_SALIDA}" &&
        "${echo_rojo}" "=> El equipo esta excluido por los grupos del usuario gráfico (6) ..."
        return 1
    fi
    
    # Comprobamos si el equipo esta incluido por Proyecto del cliente Migasfree:
    if [[ "${PROYECTOS_INCLUIDOS}" != "null" && "${PROYECTOS_INCLUIDOS}" != "all" && ! ";${PROYECTOS_INCLUIDOS};" =~ \;${PROYECTO}\; ]]; then
        "${DEBUG}" && "${echo_azul}" "${INFORMACION_SALIDA}" &&
        "${echo_rojo}" "=> El equipo no pertenece al proyecto configurado: ${PROYECTO} y debería ser ${PROYECTOS_INCLUIDOS}"
        return 1
    fi
    
    # Comprobamos si el equipo esta incluido por CID o etiquetado Migasfree:
    if [[ ";${EXCLUIDOS};" =~ \;${MIGASCID}\; || \
        "${ETIQUETAS}" =~ ${EXCLUIDOS//;/|} ]]; then
        "${DEBUG}" && "${echo_azul}" "${INFORMACION_SALIDA}" &&
        "${echo_rojo}" "=> El equipo esta excluido (1) ..."
        return 1
    fi
    
    if [[ ";${CIDSCENTRO};" =~ \;${MIGASCID}\;|all ]] ||
    [[ ";${ETIQUETASCENTRO};" =~ \;all\; ]] ||
    [[ ":${ETIQUETAS// /:}:" =~ :(${ETIQUETASCENTRO//;/|}): ]]; then
        "${echo_azul}" "${INFORMACION_SALIDA}"
        "${echo_verde}" "=> El equipo esta incluido ..."
        return 0
    else
        "${DEBUG}" && "${echo_azul}" "${INFORMACION_SALIDA}" &&
        "${echo_rojo}" "=> El equipo esta excluido (2) ..."
        return 1
    fi
}

function check_fechaini_fechafin() {
    FECHAINI="${1}"
    FECHAFIN="${2}"
    DESC="${3}"
    # Comprobamos si se han indicado fechas:
    [[ "${FECHAINI}" == "null" && "${FECHAFIN}" == "null" ]] && return 0
    # Comprobamos que las fechas se han indicado con formatos correctos:
    ! date -d "${FECHAINI}" "+%d/%m/%Y" >/dev/null 2>&1 &&
    echo "=> Fechas con formatos incorrectos, continuamos: ${FECHAINI}" && return 0
    [[ "${FECHAFIN}" != "null" ]] &&
    ! date -d "${FECHAFIN}" "+%d/%m/%Y" >/dev/null 2>&1 &&
    echo "=> Fechas con formatos incorrectos, continuamos: ${FECHAFIN}" && return 0
    # Hacemos cálculos con fechas tipo unix-timestamps (segundos desde 1.1.1970 0:0:0) para saber si toca ejecutar la tarea:
    TODAY="$(date "+%Y-%m-%d %H:%M:%S")"
    TODAYMS="$(date -d "${TODAY}" "+%s")"
    FECHAINIMS="$(date -d "${FECHAINI}" "+%s")"
    [[ ${TODAYMS} -lt ${FECHAINIMS} ]] &&
    "${echo_rojo}" "#> No ha llegado el día para ejecutar \"${DESC}\": ${TODAY} < ${FECHAINI}" &&
    return 1
    # Comprobamos la fecha final para la ejecución de la tarea:
    if [[ "${FECHAFIN}" != "null" ]]; then
        FECHAFINMS="$(date -d "${FECHAFIN}" "+%s")"
        [[ ${TODAYMS} -gt ${FECHAFINMS} ]] &&
        "${echo_rojo}" "#> Ha pasado el intérvalo de días para ejecutar \"${DESC}\": ${TODAY} > ${FECHAFIN}" &&
        return 1
    fi
    return 0
}

function check_ejecutar_una_vez() {
    _UNA_VEZ="${1}"
    _PARAM="${2^^}" # Recogemos el Parámetro todo en mayúsculas, para ser fieles al uso de variables en mayúsculas en bash
    _NUM="${3}"
    #  Comprobamos si se tiene que ejecutar sólo una vez:
    [[ "${_UNA_VEZ}" == "null" ]] && return 0
    # Comprobamos si la variable ya existe en el fichero de variables para saber si ya se ha ejecutado una vez:
    CLAVE="${_PARAM//./_}_${_NUM}_${_UNA_VEZ}"
    vx-set-fich_vars -e -f "${FICH_VARS_CONF_CENTRO}" -c "${CLAVE}" -v "1" > /dev/null 2>&1 && \
    return 0 || \
    return 1
}

function check_parametro() {
    PARAM="${1}"
    NUM=$(jq ".${PARAM} | length" <<<"${JSON}" 2>/dev/null || echo "0")
    [ -z "${NUM}" ] && NUM="0"
    CONT=0
    ((NUM > 0)) && echo "=> Personalización [${2}]: ${NUM}"
    while ((${CONT} < ${NUM})) && [[ ${NUM} =~ ^[[:digit:]]*$ ]]; do
        # Los CIDS recibidos deben estar separados por ";"
        CIDSCENTRO="$(jq -r ".${PARAM}[${CONT}] | .cids" <<<"${JSON}")"
        # Las ETIQUETAS recibidas deben estar separadas por ";"
        ETIQUETASCENTRO="$(jq -r ".${PARAM}[${CONT}] | .etiquetas" <<<"${JSON}")"
        # Comprobamos los excluidos:
        EXCLUIDOS="$(jq -r ".${PARAM}[${CONT}] | .excluidos" <<<"${JSON}")"
        # Obtenemos una Descripción de lo que se va a configurar:
        DESC="$(jq -r ".${PARAM}[${CONT}] | .desc" <<<"${JSON}")"
        # Obtenemos la lista de usuarios y grupos de la sesión gráfica en que debe configurarse:
        ALLOW_USERS="$(jq -r ".${PARAM}[${CONT}] | .users" <<<"${JSON}")"
        ALLOW_GROUPS="$(jq -r ".${PARAM}[${CONT}] | .groups" <<<"${JSON}")"
        DENY_USERS="$(jq -r ".${PARAM}[${CONT}] | .\"users-excluidos\"" <<<"${JSON}")"
        DENY_GROUPS="$(jq -r ".${PARAM}[${CONT}] | .\"groups-exluidos\"" <<<"${JSON}")"
        PROYECTOS_INCLUIDOS="$(jq -r ".${PARAM}[${CONT}] | .proyectos" <<<"${JSON}")"
        FECHAINI="$(jq -r ".${PARAM}[${CONT}] | .fechaini" <<<"${JSON}")"
        FECHAFIN="$(jq -r ".${PARAM}[${CONT}] | .fechafin" <<<"${JSON}")"
        UNA_VEZ="$(jq -r ".${PARAM}[${CONT}] | .unavez" <<<"${JSON}")"
        if check_cids_etiquetas_usuarios_grupos_proyecto \
        "${CONT}" "${CIDSCENTRO}" "${ETIQUETASCENTRO}" "${EXCLUIDOS}" "${DESC}" \
        "${ALLOW_USERS}" "${ALLOW_GROUPS}" "${DENY_USERS}" "${DENY_GROUPS}" "${PROYECTOS_INCLUIDOS}" \
        "${FECHAINI}" "${FECHAFIN}" &&
        check_fechaini_fechafin "${FECHAINI}" "${FECHAFIN}" "${DESC}" && \
        check_ejecutar_una_vez "${UNA_VEZ}" "${PARAM}" "${NUM}" ; then
            "${3}" "${PARAM}" "${CONT}"
        fi
        ((CONT++))
    done
}

DIRSCRIPTS="/usr/share/vitalinux/conf-centro/scripts-funcs"
AYUDA='#> Ayuda: Para aplicar la configuracion de centro debes hacer uso de sudo (privilegios de root).
# En caso de no pasar ningun parametro se ejectuaran todos los scripts ubicados en "'"${DIRSCRIPTS}"'".
# Tienes la opcion de ejecutar solo ciertos scripts indicando su numero:
'"$(ls "${DIRSCRIPTS}" | grep -E "*.sh")"
EJEMPLOS=("${0}")
EJEMPLOS+=("${0} \"-h|--help\"")
EJEMPLOS+=("${0} \"01\" \"03\" \"12\"")
# Comprobamos que el usuario root es el que llama al script o si se solicita ayuda:
if vx-check_need_help "${1}" || [[ "$(whoami)" != "root" ]] ; then
    vx-show_help "${0}" "${AYUDA}" "${EJEMPLOS[@]}" && exit 0
fi

echo "=> Ok: Configuramos el equipo de centro como usuario \"root\""

# 0) Preparamos la auditoria de la configuración de centro:
[[ "$(LC_ALL=C type -t "vx-log_xsession")" == "function" ]] &&
FICHLOG="vx-conf-pre-centro.log" &&
vx-log_xsession -o "${FICHLOG}" &&
"${echo_azul}" "## $(date) ##\nAuditoria de configuración de centro ${CENTRO}: ${FICHLOG}\n##"

# 1) Comprobamos que hay un archivo Json de personalización de centro:
MENSAJE="No existe ningún fichero Json de personalización de centro"
FICHCONFJSON="/usr/share/vitalinux/conf-centro/vx-centro.conf.json"
[ ! -f "${FICHCONFJSON}" ] &&
{
    mensaje "${MENSAJE}" && exit 1
} ||
"${echo_verde}" "=> Usamos como fichero Json de configuración de centro: ${FICHCONFJSON}"

# Comprobamos si hay secciones que actualizar en el fichero JSON por personalizaciones del centro:
DIR_SECCIONES="/usr/share/vitalinux/conf-centro/secciones"
if [[ -d "${DIR_SECCIONES}" ]] ; then
    echo "#> ${DIR_SECCIONES}: Personalizamos las secciones del JSON de configuración del centro"
    vx-conf-centro-json-personalizar_secciones -f "${FICHCONFJSON}" -d "${DIR_SECCIONES}"
    sync
fi

# Cargamos el archivo JSON Principal en una variable para agilizar su posterior manipulación:
JSON="$(<"${FICHCONFJSON}")"

CENTRO="$(jq -r ".centro" <<<"${JSON}")"
[ -z "${CENTRO}" ] && exit 1 ||
echo "=> Centro: ${CENTRO}"

# 2) Comprobamos las etiquetas y CID del equipo:
"${echo_azul}" "=> Comprobamos las etiquetas y CID del equipo ..."
ETIQUETAS="$(vx-migasfree-tags -g)" || exit 1

# Comprobamos que ETIQUETAS no esta vácio, y por tanto, tiene al menos una etiqueta de centro:
((${#ETIQUETAS} < 3)) &&
echo "=> El equipo tiene etiquetas Migasfree no reconocidas, salimos antes de tiempo." &&
exit 0

echo "=> Etiquetas Migasfree: $(echo ${ETIQUETAS} | tr -s "\n" " ")"

if test -f "/usr/bin/migasfree-cid"; then
    MIGASCID=$(/usr/bin/migasfree-cid)
fi
echo "=> CID: ${MIGASCID}"

# 3) Lanzamos los scripts de personalización de centro:
# Comprobamos si se ha pasado como parametro algun script a ejecutar o se ejecutan todos:
MENSAJE="No existe \"${DIRSCRIPTS}\". No hay scripts que ejecutar"
[[ ! -d "${DIRSCRIPTS}" ]] && echo_rojo "${MENSAJE}" && exit 1
REGEX="^[[:digit:]]{2}$"
if [[ -z "${1}" ]] ; then
    for SCRIPT in "${DIRSCRIPTS}/"*.sh; do
        . "${SCRIPT}"
    done
else
    while [[ ! -z "${1}" ]] ; do
        [[ ! "${1}" =~ $REGEX ]] && echo "#> ${1}: No se puede ejecutar al no ser un numero de script" && shift && continue
        SCRIPT="$(find ${DIRSCRIPTS} -name "${1}*.sh")"
        [[ -f "${SCRIPT}" ]] && . "${SCRIPT}"
        shift
    done
fi

## FIN de la Configuración de Centro ##
echo "=> $(date) - FIN de la Configuración de Centro"
