#!/bin/bash

#####################################################################
####### Script instalador Ogclient
####### Autor: Luis Gerardo Romero <lgromero@qindel.es>
#####################################################################

function globalSetup() {
    local current_dir
    current_dir=$(dirname "$0")
    PROGRAMDIR=$(readlink -e "$current_dir")
    PROGRAMNAME=$(basename "$0")
    OPENGNSYS_CLIENT_USER="ogboot"

    # Comprobar si se ha descargado el paquete comprimido (REMOTE=0) o sólo el instalador (REMOTE=1).
    if [ -d "$PROGRAMDIR/../installer" ]; then
        echo "REMOTE=0"
        REMOTE=0
    else
        echo "REMOTE=1"
        REMOTE=1
    fi

    BRANCH=${1:-"main"}

    if (( $# > 1 )); then
    CLIENTS=("${@:2}")
    fi

    GIT_REPO="ssh://git@ognproject.evlt.uma.es:21987/opengnsys/ogboot.git"

    # Directorios de instalación y destino de OpenGnsys.
    WORKDIR=/tmp/ogboot_installer
    INSTALL_TARGET=/opt/ogboot
    PATH=$PATH:$INSTALL_TARGET/bin

    if command -v service &>/dev/null; then
        STARTSERVICE="eval service \$service restart"
        STOPSERVICE="eval service \$service stop"
    else
        STARTSERVICE="eval /etc/init.d/\$service restart"
        STOPSERVICE="eval /etc/init.d/\$service stop"
    fi

    ENABLESERVICE="eval update-rc.d \$service defaults"
    DISABLESERVICE="eval update-rc.d \$service disable"

    APACHESERV=apache2
    APACHECFGDIR=/etc/apache2
    APACHESITESDIR=sites-available
    APACHEOGSITE=ogboot
    APACHEUSER="www-data"
    APACHEGROUP="www-data"
    APACHEENABLEMODS="a2enmod headers ssl rewrite proxy_fcgi fastcgi actions alias"
    APACHEENABLESSL="a2ensite default-ssl"
    APACHEENABLEOG="a2ensite $APACHEENABLEOG"
    APACHEMAKECERT="make-ssl-cert generate-default-snakeoil --force-overwrite"
	SAMBASERV=smbd
	SAMBACFGDIR=/etc/samba
	TFTPCFGDIR=/var/lib/tftpboot
    TFTPSERV=tftp
    INETDSERV=xinetd
    INETDCFGDIR=/etc/xinetd.d

    PHPFPMSERV=php7.2-fpm

    # Registro de incidencias.
    OGLOGFILE="$INSTALL_TARGET/var/log/${PROGRAMNAME%.sh}.log"
    LOG_FILE="/tmp/$(basename "$OGLOGFILE")"
}


function checkDependencies() {
    echoAndLog "Checking dependencies..."

    # Lista de dependencias
	
local DEPENDENCIES=(
    php
    php-cli
    php-fpm
    php-json
    php-pdo
    php-mysql
    php-zip
    php-gd
    php-mbstring
    php-curl
    php-xml
    php-pear
    php-bcmath
    composer
    unzip
    apache2
    libapache2-mod-php
    subversion
    php-ldap
    isc-dhcp-server
    bittorrent
    tftp-hpa
    tftpd-hpa
    xinetd
    build-essential
    g++-multilib
    wget
    curl
    graphviz
    bittornado
    ctorrent
    samba
    rsync
    netpipes
    debootstrap
    schroot
    squashfs-tools
    btrfs-tools
    procps
    arp-scan
    realpath
    gettext
    moreutils
    jq
    wakeonlan
    udpcast
    libev-dev
    libjansson-dev
    libssl-dev
    shim-signed
    grub-efi-amd64-signed
    gawk
    libdbi-dev
    libdbi1
    automake
    liblz4-tool
)

    # Comprobar cada dependencia
    for dep in "${DEPENDENCIES[@]}"; do
        if ! dpkg -s "$dep" >/dev/null 2>&1; then
            echoAndLog "$dep is not installed. Installing..."
            sudo apt-get install -y "$dep"
        else
            echoAndLog "$dep is already installed."
        fi
    done

    echoAndLog "Dependencies checked."
}

# Ejecutar la función para generar la URL y ejecutar el curl
install_kea() {
    local url=$(generate_config_url)
    echo "URL generada: $url"
    echo "Ejecutando curl para obtener el archivo de configuración del repositorio KEA..."
    curl -1sLf "$url" > /etc/apt/sources.list.d/isc-kea-2-0.list
    echo "El archivo de configuración del repositorio KEA ha sido guardado en /etc/apt/sources.list.d/isc-kea-2-0.list"

    echo "Descargando y agregando la clave GPG del repositorio KEA..."
    curl -1sLf "https://dl.cloudsmith.io/public/isc/kea-2-0/gpg.8029D4AFA58CBB5E.key" | gpg --dearmor >> /usr/share/keyrings/isc-kea-2-0-archive-keyring.gpg
    echo "La clave GPG del repositorio KEA ha sido descargada y agregada correctamente"

    echo "Ejecutando apt-get update..."
    apt-get update

    echo "Comprobando disponibilidad de los paquetes..."
    if apt-cache show isc-kea-common &>/dev/null; then
        echo "El paquete isc-kea-common está disponible para ser instalado."
        echo "Descargando e instalando el paquete isc-kea-common..."
        apt-get install -y isc-kea-common
        echo "El paquete isc-kea-common ha sido descargado e instalado correctamente."
    else
        echo "El paquete isc-kea-common no está disponible en los repositorios apt."
    fi

    if apt-cache show isc-kea-dhcp4-server &>/dev/null; then
        echo "El paquete isc-kea-dhcp4-server está disponible para ser instalado."
        echo "Descargando e instalando el paquete isc-kea-dhcp4-server..."
        apt-get install -y isc-kea-dhcp4-server
        echo "El paquete isc-kea-dhcp4-server ha sido descargado e instalado correctamente."
    else
        echo "El paquete isc-kea-dhcp4-server no está disponible en los repositorios apt."
    fi

    if apt-cache show isc-kea-dhcp6-server &>/dev/null; then
        echo "El paquete isc-kea-dhcp6-server está disponible para ser instalado."
        echo "Descargando e instalando el paquete isc-kea-dhcp6-server..."
        apt-get install -y isc-kea-dhcp6-server
        echo "El paquete isc-kea-dhcp6-server ha sido descargado e instalado correctamente."
    else
        echo "El paquete isc-kea-dhcp6-server no está disponible en los repositorios apt."
    fi

    if apt-cache show isc-kea-dhcp-ddns-server &>/dev/null; then
        echo "El paquete isc-kea-dhcp-ddns-server está disponible para ser instalado."
        echo "Descargando e instalando el paquete isc-kea-dhcp-ddns-server..."
        apt-get install -y isc-kea-dhcp-ddns-server
        echo "El paquete isc-kea-dhcp-ddns-server ha sido descargado e instalado correctamente."
    else
        echo "El paquete isc-kea-dhcp-ddns-server no está disponible en los repositorios apt."
    fi

    if apt-cache show isc-kea-ctrl-agent &>/dev/null; then
        echo "El paquete isc-kea-ctrl-agent está disponible para ser instalado."
        echo "Descargando e instalando el paquete isc-kea-ctrl-agent..."
        apt-get install -y isc-kea-ctrl-agent
        echo "El paquete isc-kea-ctrl-agent ha sido descargado e instalado correctamente."
    else
        echo "El paquete isc-kea-ctrl-agent no está disponible en los repositorios apt."
    fi
}

# Función para configurar el servicio DHCP de Kea
function keaDhcpConfigure() {
    echoAndLog "${FUNCNAME}(): Configuración de muestra para el servicio DHCP de Kea."

    local errcode=0
    local i=0
    local interfaces="["

    # Construir la lista de interfaces
    for dev in "${DEVICE[@]}"; do
        if [ $i -ne 0 ]; then
            interfaces+=", "
        fi
        interfaces+="\"$dev\""
        let i++
    done
    interfaces+="]"

    # Respalda el archivo de configuración existente
    backupFile "/etc/kea/kea-dhcp4.conf"

    # Sustituye los parámetros en la plantilla y guarda el archivo de configuración
	echoAndLog "$NETIP"
	echoAndLog "$NETMASK"
	CIDR=$(mask2cidr $NETMASK)
    echoAndLog $CIDR  # Salida: 24
	echoAndLog "$ROUTERIP"
	echoAndLog "$DNSIP"
    sed -e "s|\"interfaces\": \"INTERFACES\"|\"interfaces\": $interfaces|" \
	    -e "s/SERVERIP/${SERVERIP}/g" \
        -e "s/NETIP/${NETIP}/g" \
        -e "s/NETMASK/${CIDR}/g" \
        -e "s/ROUTERIP/${ROUTERIP}/g" \
        -e "s/DNSIP/${DNSIP}/g" \
        "$WORKDIR/ogboot/etc/kea-dhcp4.conf.tmpl" > "/etc/kea/kea-dhcp4.conf" || errcode=1

    # Si hubo errores al configurar, muestra un mensaje de error y sale de la función
    if [ $errcode -ne 0 ]; then
        errorAndLog "${FUNCNAME}(): Error al configurar el servicio DHCP de Kea."
        return 1
    fi


    echoAndLog "${FUNCNAME}(): Configuración de muestra para el servicio DHCP de Kea configurada en \"/etc/kea/kea-dhcp4.conf\"."
    return 0
}
# Función para instalar Composer
install_composer() {
    curl -sS https://getcomposer.org/installer | php
    sudo mv composer.phar /usr/local/bin/composer
}

# Función para instalar Swagger UI
install_swagger() {
    sudo apt-get install -y unzip
    wget https://github.com/swagger-api/swagger-ui/archive/master.zip
    unzip master.zip -d /var/www/html/
    sudo mv /var/www/html/swagger-ui-master /var/www/html/swagger-ui
}

# Obtiene el código fuente del proyecto desde el repositorio de GitHub.
function downloadCode() {
    if [ $# -ne 1 ]; then
        errorAndLog "${FUNCNAME}(): invalid number of parameters"
        exit 1
    fi

    local url="$1"

    echoAndLog "${FUNCNAME}(): downloading code from '$url'..."

    GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=accept-new" git archive --remote="$url" --format zip --output opengnsys.zip --prefix=opengnsys/ "$BRANCH" && unzip opengnsys.zip
    if [ $? -ne 0 ]; then
        errorAndLog "${FUNCNAME}(): error getting OpenGnsys code from $url"
        return 1
    fi
    rm -f opengnsys.zip
    echoAndLog "${FUNCNAME}(): code was downloaded"
    return 0
}

# Crea la estructura base de la instalación de opengnsys
function createDirs() {
    if [ $# -ne 1 ]; then
        errorAndLog "${FUNCNAME}(): invalid number of parameters"
        exit 1
    fi

    local path_opengnsys_base="$1"

	# Crear estructura de directorios.
	echoAndLog "${FUNCNAME}(): creating directory paths in $path_opengnsys_base"
	mkdir -p $path_opengnsys_base
	mkdir -p $path_opengnsys_base/bin
	mkdir -p $path_opengnsys_base/client
	mkdir -p $path_opengnsys_base/doc
	mkdir -p $path_opengnsys_base/etc
	mkdir -p $path_opengnsys_base/lib
	mkdir -p $path_opengnsys_base/log/clients
	ln -fs $path_opengnsys_base/log /var/log/opengnsys
	mkdir -p $path_opengnsys_base/sbin
	mkdir -p $path_opengnsys_base/www
	mkdir -p $path_opengnsys_base/images/groups
	mkdir -p $TFTPCFGDIR
	ln -fs $TFTPCFGDIR $path_opengnsys_base/tftpboot
	mkdir -p $path_opengnsys_base/tftpboot/{menu.lst,grub}
	if [ $? -ne 0 ]; then
		errorAndLog "${FUNCNAME}(): error while creating dirs. Do you have write permissions?"
		return 1
	fi

    # Crear estructura de directorios.
    #echoAndLog "${FUNCNAME}(): creating directory paths in $path_opengnsys_base"
    #mkdir -p "$path_opengnsys_base"/{bin,config,docs,public,src,etc/kea/backup,templates,var/{cache,log},vendor, tftpboot}
    #if [ $? -ne 0 ]; then
    #    errorAndLog "${FUNCNAME}(): error while creating dirs. Do you have write permissions?"
    #    return 1
    #fi

    # Crear usuario ficticio.
    if id -u "$OPENGNSYS_CLIENT_USER" &>/dev/null; then
        echoAndLog "${FUNCNAME}(): user \"$OPENGNSYS_CLIENT_USER\" is already created"
    else
        echoAndLog "${FUNCNAME}(): creating OpenGnsys user"
        useradd "$OPENGNSYS_CLIENT_USER" 2>/dev/null
        if [ $? -ne 0 ]; then
            errorAndLog "${FUNCNAME}(): error creating OpenGnsys user"
            return 1
        fi
    fi

    # Mover el fichero de registro de instalación al directorio de logs.
    echoAndLog "${FUNCNAME}(): moving installation log file"
    mv "$LOG_FILE" "$path_opengnsys_base/var/log" && LOG_FILE="$OGLOGFILE"
    chmod 777 "$LOG_FILE"
    sudo chmod -R 777 "$path_opengnsys_base/etc"

    # Mover el fichero de registro de instalación al directorio de logs.
    echoAndLog "${FUNCNAME}(): moving installation log file"
    touch "$path_opengnsys_base/var/log/dev.log"
    chmod 777 "$path_opengnsys_base/var/log/dev.log"

    echoAndLog "${FUNCNAME}(): directory paths created"
    return 0

    # Cambiar permisos de usuario
    echoAndLog "Changing user permission"
    chown -R "$OPENGNSYS_CLIENT_USER:$OPENGNSYS_CLIENT_USER" "$INSTALL_TARGET"

    # Copiar .env
    cp -a "$WORKDIR/ogboot/.env" "${path_opengnsys_base}/.env"
}

function create_ogboot_project {
    # Cambia al usuario ogboot y crea el proyecto Symfony
    local path_opengnsys_base="$1"
    composer create-project symfony/website-skeleton "$path_opengnsys_base"
    pushd "$path_opengnsys_base" || return
    # Elimina el archivo composer.lock
    rm composer.lock
    popd || return
    echoAndLog "Esqueleto de la aplicación creado y archivo composer.lock eliminado."
}


function copyServerFiles() {
    if [ $# -ne 1 ]; then
        errorAndLog "${FUNCNAME}(): invalid number of parameters"
        exit 1
    fi

    local path_opengnsys_base="$1"

    # Lista de ficheros y directorios origen y de directorios destino.
    local SOURCES=(
        tftpboot 
        bin
        doc
        etc
        client
    )
    local TARGETS=(
        tftpboot
        bin
        doc
        etc
        client
    )

    if [ "${#SOURCES[@]}" != "${#TARGETS[@]}" ]; then
        errorAndLog "${FUNCNAME}(): inconsistent number of array items"
        exit 1
    fi

    # Copiar ficheros.
    echoAndLog "${FUNCNAME}(): copying files to server directories"

    pushd "$WORKDIR/ogboot" || return
    local i
    for (( i = 0; i < ${#SOURCES[@]}; i++ )); do
        if [ -f "${SOURCES[$i]}" ]; then
            echoAndLog "Copying ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}"
            cp -a "${SOURCES[$i]}" "$path_opengnsys_base/${TARGETS[$i]}"
        elif [ -d "${SOURCES[$i]}" ]; then
            echoAndLog "Copying content of ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}"
            cp -a "${SOURCES[$i]}"/* "$path_opengnsys_base/${TARGETS[$i]}"
        else
            warningAndLog "Unable to copy ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}"
        fi
    done
    echoAndLog "Changing user permission"
    chown -R "$OPENGNSYS_CLIENT_USER:$OPENGNSYS_CLIENT_USER" "$INSTALL_TARGET"

    popd || return
}


# Obtener los parámetros de red de la interfaz por defecto.
function getNetworkSettings()
{
	# Arrays globales definidas:
	# - DEVICE:     nombres de dispositivos de red activos.
	# - SERVERIP:   IPs locales del servidor.
	# - NETIP:      IPs de redes.
	# - NETMASK:    máscaras de red.
	# - NETBROAD:   IPs de difusión de redes.
	# - ROUTERIP:   IPs de routers.
	# Otras variables globales:
	# - DEFAULTDEV: dispositivo de red por defecto.
	# - DNSIP:      IP del servidor DNS principal.

	local i=0
	local dev=""

	echoAndLog "${FUNCNAME}(): Detecting network parameters."
	DEVICE=( $(ip -o link show up | awk '!/loopback/ {sub(/[:@].*/,"",$2); print $2}') )
	if [ -z "$DEVICE" ]; then
		errorAndLog "${FUNCNAME}(): Network devices not detected."
		exit 1
	fi
	for dev in ${DEVICE[*]}; do
		SERVERIP[i]=$(ip -o addr show dev "$dev" | awk '$3~/inet$/ {sub (/\/.*/, ""); print ($4); exit;}')
		if [ -n "${SERVERIP[i]}" ]; then
			NETMASK[i]=$( cidr2mask $(ip -o addr show dev "$dev" | awk '$3~/inet$/ {sub (/.*\//, "", $4); print ($4); exit;}') )
			NETBROAD[i]=$(ip -o addr show dev "$dev" | awk '$3~/inet$/ {print ($6); exit;}')
			NETIP[i]=$(ip route list proto kernel | awk -v d="$dev" '$3==d && /src/ {sub (/\/.*/,""); print $1; exit;}')
			ROUTERIP[i]=$(ip route list default | awk -v d="$dev" '$5==d {print $3; exit;}')
			if [ $DHCPNET == ${NETIP[i]} ]; then
				DEFAULTDEV="$dev"
			else
				DEFAULTDEV=${DEFAULTDEV:-"$dev"}
			fi
		fi
		let i++
	done
	DNSIP=$(systemd-resolve --status 2>/dev/null | awk '/DNS Servers:/ {print $3; exit;}')
	[ -z "$DNSIP" ] && DNSIP=$(awk '/nameserver/ {print $2; exit;}' /etc/resolv.conf)
	if [ -z "${NETIP[*]}" -o -z "${NETMASK[*]}" ]; then
		errorAndLog "${FUNCNAME}(): Network not detected."
		exit 1
	fi

}


#####################################################################
#### Funciones de compilación de código fuente de servicios
#####################################################################

# Compilar los servicios de OpenGnsys
function servicesCompilation ()
{
	local hayErrores=0

	# Compilar OpenGnsys Client
	echoAndLog "${FUNCNAME}(): Compiling OpenGnsys Admin Client"
	pushd $WORKDIR/ogboot/sources/clients/ogAdmClient
	make && mv ogAdmClient ../../../client/shared/bin
	if [ $? -ne 0 ]; then
		echoAndLog "${FUNCNAME}(): error while compiling OpenGnsys Admin Client"
		hayErrores=1
	fi
	popd

	return $hayErrores
}
#REVISAR SI HACE FALTA Y COMO ESTRUCTURARLO!!!!!!!##################
###################################################################
## Funciones instalacion cliente opengnsys
###################################################################
function copyClientFiles()
{
	local errstatus=0

	echoAndLog "${FUNCNAME}(): Copying OpenGnsys Client files."
	cp -a $WORKDIR/ogboot/client/shared/* $INSTALL_TARGET/client
	if [ $? -ne 0 ]; then
		errorAndLog "${FUNCNAME}(): error while copying client estructure"
		errstatus=1
	fi

	echoAndLog "${FUNCNAME}(): Copying OpenGnsys Cloning Engine files."
	mkdir -p $INSTALL_TARGET/client/lib/engine/bin
	cp -a $WORKDIR/ogboot/client/engine/*.lib* $INSTALL_TARGET/client/lib/engine/bin
	if [ $? -ne 0 ]; then
		errorAndLog "${FUNCNAME}(): error while copying engine files"
		errstatus=1
	fi

	if [ $errstatus -eq 0 ]; then
		echoAndLog "${FUNCNAME}(): client copy files success."
	else
		errorAndLog "${FUNCNAME}(): client copy files with errors"
	fi

	return $errstatus
}


generate_ipxe_script() {

	echo "Generando script IPXE..."
	ip_address_server=$(ifconfig eth0 | awk '/inet / {print $2}')
	template="$WORKDIR/ogboot/etc/dhcp_boot.ipxe.tmpl"

	ipxe_output="/opt/opengnsys/tftpboot/ipxe_scripts/dhcp_boot.ipxe"

	# Reemplazar SERVERIP con la dirección IP en la plantilla y guardarla en el archivo de salida
	sed "s/SERVERIP/$ip_address_server/g" "$template" > "$ipxe_output"

	template_default="tftpboot/ipxe_scripts/default.ipxe"

	default_output="/opt/opengnsys/tftpboot/ipxe_scripts/default.ipxe"

    mac_script_template="etc/mac_script.ipxe.tmpl"

    sed "s/SERVERIP/$ip_address_server/g" "$template_default" > "$default_output"
	echo "Creando ficheros MAC script"

    echo "Archivos creados correctamente."
	


}


function tftpConfigure()
{
	echoAndLog "${FUNCNAME}(): Configuring TFTP service."
	# Habilitar TFTP y reiniciar Inetd.
	if [ -n "$TFTPSERV" ]; then
		if [ -f $INETDCFGDIR/$TFTPSERV ]; then
			perl -pi -e 's/disable.*/disable = no/' $INETDCFGDIR/$TFTPSERV
		else
			service=$TFTPSERV
			$ENABLESERVICE; $STARTSERVICE
		fi
	fi
	service=$INETDSERV
	$ENABLESERVICE; $STARTSERVICE

	# comprobamos el servicio tftp
	sleep 1
	testPxe
}

# Comprueba que haya conexión al servicio TFTP/PXE.
function testPxe ()
{
	echoAndLog "${FUNCNAME}(): Checking TFTP service... please wait."
	echo "test" >$TFTPCFGDIR/testpxe
	tftp -v 127.0.0.1 -c get testpxe /tmp/testpxe && echoAndLog "TFTP service is OK." || errorAndLog "TFTP service is down."
	rm -f $TFTPCFGDIR/testpxe /tmp/testpxe
}

mount_NFS() {
    if sudo mount -t nfs ognartefactos.evlt.uma.es:/ /mnt; then
        echo "Sistema NFS montado correctamente."
    else
        echo "Error: No se pudo montar el sistema NFS."
        exit 1
    fi

    ls /mnt/

    sudo cp -r /mnt/srv/artefactos/ipxe/ /tmp

    cd /tmp/ipxe/src
    if sudo make -j 4; then
        echo "Directorio /tmp/ipxe/src montado correctamente."
    else
        echo "Error: No se pudo montar el directorio /tmp/ipxe/src."
        exit 1
    fi

    if sudo make bin/undionly.kpxe EMBED=/opt/opengnsys/tftpboot/ipxe_scripts/dhcp_boot.ipxe; then
        echo "Fichero de arranque montado correctamente."
    else
        echo "Error: No se pudo montar el fichero de arranque."
        exit 1
    fi

    sudo cp bin/undionly.kpxe /opt/opengnsys/tftpboot

    if sudo make bin-x86_64-efi/ipxe.efi EMBED=/opt/opengnsys/tftpboot/ipxe_scripts/dhcp_boot.ipxe; then
        echo "Fichero EFI construido correctamente."
    else
        echo "Error: No se pudo construir el fichero EFI."
        exit 1
    fi

    sudo cp bin-x86_64-efi/ipxe.efi /opt/opengnsys/tftpboot

}

########################################################################
## Configuración servicio Samba
########################################################################

# Configurar servicios Samba.
function smbConfigure()
{
	echoAndLog "${FUNCNAME}(): Configuring Samba service."

	backupFile $SAMBACFGDIR/smb.conf
	
	# Copiar plantailla de recursos para OpenGnsys
        sed -e "s/OGBOOTDIR/${INSTALL_TARGET//\//\\/}/g" \
		$WORKDIR/ogboot/etc/smb-ogboot.conf.tmpl > $SAMBACFGDIR/smb-ogboot.conf
	# Configurar y recargar Samba"
	perl -pi -e "s/WORKGROUP/OPENGNSYS/; s/server string \=.*/server string \= ogBoot Samba Server/" $SAMBACFGDIR/smb.conf
	if ! grep -q "smb-ogboot" $SAMBACFGDIR/smb.conf; then
		echo "include = $SAMBACFGDIR/smb-ogboot.conf" >> $SAMBACFGDIR/smb.conf
	fi
	service=$SAMBASERV
	$ENABLESERVICE; $STARTSERVICE
	if [ $? -ne 0 ]; then
		errorAndLog "${FUNCNAME}(): error while configure Samba"
		return 1
	fi
	# Crear clave para usuario de acceso a los recursos.
	echo -ne "$OPENGNSYS_CLIENT_PASSWD\n$OPENGNSYS_CLIENT_PASSWD\n" | smbpasswd -a -s $OPENGNSYS_CLIENT_USER

	echoAndLog "${FUNCNAME}(): Added Samba configuration."
	return 0
}

####################################################################
####################################################################
############# - INSTALACIÓN DE SYMFONY+SWAGGER - ###################
###################################################################
#POR AHORA NO SE INSTALARÁ HASTA MERGEAR RAMA DE SYMFONY###########
####################################################################
####################################################################

#function downloadComposer() {
#    echoAndLog "Downloading composer.phar..."
#
#    # Crear el directorio de trabajo si no existe
#    mkdir -p "$WORKDIR/ogboot/bin" || return
#
#    # Cambiar al directorio de trabajo
#    pushd "$WORKDIR/ogboot/bin" || return
#
#    # Descargar composer.phar
#    curl -sS https://getcomposer.org/installer | php
#
#    # Comprobar si la descarga fue exitosa
#    if [ ! -f composer.phar ]; then
#        errorAndLog "Failed to download composer.phar"
#        popd
#        return 1
#    fi
#
#    # Crear el directorio de destino si no existe
#    mkdir -p "/opt/ogboot/bin" || return
#
#    # Mover composer.phar a /opt/ogboot/bin
#    mv composer.phar "/opt/ogboot/bin/"
#
#    # Comprobar si el movimiento fue exitoso
#    if [ ! -f "/opt/ogboot/bin/composer.phar" ]; then
#        errorAndLog "Failed to move composer.phar to /opt/ogboot/bin"
#        popd
#        return 1
#    fi
#
#    # Volver al directorio original
#    popd || return
#
#    echoAndLog "composer.phar downloaded and moved to /opt/ogboot/bin"
#    return 0
#}



#function runComposer() {
#    echoAndLog "Running composer.phar to install dependencies..."
#
#    # Cambiar al directorio donde está composer.phar
#    pushd /opt/ogboot/bin || return
#
#    # Ejecutar composer.phar
#    sudo -u "$OPENGNSYS_CLIENT_USER" php composer.phar install
#
#    # Comprobar si la ejecución fue exitosa
#    if [ $? -ne 0 ]; then
#        errorAndLog "Failed to run composer.phar"
#        popd
#        return 1
#    fi
#
#    # Volver al directorio original
#    popd || return
#
#    echoAndLog "composer.phar ran successfully and dependencies were installed"
#    return 0
#}
#
#function install_swagger_ui {
#    # Define la URL del archivo de Swagger UI que quieres descargar
#    swagger_ui_url="https://github.com/swagger-api/swagger-ui/archive/refs/heads/master.zip"
#
#    # Define la ruta donde quieres descomprimir Swagger UI
#    swagger_ui_path="/tmp/swagger-ui"
#
#    # Define la ruta de destino para los archivos de Swagger UI
#    destination_path="/opt/ogboot/public"
#
#    # Crea los directorios si no existen
#    mkdir -p "$swagger_ui_path"
#    mkdir -p "$destination_path"
#
#    # Descarga el archivo de Swagger UI
#    wget "$swagger_ui_url" -O /tmp/swagger-ui.zip
#
#    # Descomprime el archivo de Swagger UI en la ruta especificada
#    unzip /tmp/swagger-ui.zip -d "$swagger_ui_path"
#
#    # Copia los archivos de Swagger UI al directorio de destino
#    cp -r "$swagger_ui_path"/swagger-ui-master/dist/* "$destination_path"
#
#    # Elimina el archivo descargado y el directorio temporal
#    rm /tmp/swagger-ui.zip
#    rm -r "$swagger_ui_path"
#    /opt/ogboot/vendor/bin/openapi /opt/ogboot/src/DhcpBundle/Controller/ -o "$destination_path/swagger.json"
#    echo "Swagger UI instalado en $destination_path."
#}
#
#function installWebConsoleApacheConf() {
#    if [ $# -ne 2 ]; then
#        errorAndLog "${FUNCNAME}(): invalid number of parameters"
#        exit 1
#    fi
#
#    local path_opengnsys_base="$1"
#    local path_apache2_confd="$2"
#    local OGHDPCDIR="${path_opengnsys_base}/public"
#    local sockfile
#
#    if [ ! -d "$path_apache2_confd" ]; then
#        errorAndLog "${FUNCNAME}(): path to apache2 conf.d can not found, verify your server installation"
#        return 1
#    fi
#
#    mkdir -p "$path_apache2_confd/{sites-available,sites-enabled}"
#
#    echoAndLog "${FUNCNAME}(): creating apache2 config file.."
#
#    # Activar PHP-FPM.
#    echoAndLog "${FUNCNAME}(): configuring PHP-FPM"
#    service="$PHPFPMSERV"
#    $ENABLESERVICE; $STARTSERVICE
#    sockfile=$(find /run/php -name "php*.sock" -type s -print 2>/dev/null | tail -1)
#
#    # Activar módulos de Apache.
#    $APACHEENABLEMODS
#
#    # Generar configuración de consola web a partir del archivo de plantilla.
#    if [ -n "$sockfile" ]; then
#        sed -e "s,OGHDPCDIR,$OGHDPCDIR,g" \
#            -e "s,proxy:fcgi:.*,proxy:unix:${sockfile%% *}|fcgi://localhost\",g" \
#            "$WORKDIR/ogboot/etc/apache.conf.tmpl" > "$path_apache2_confd/$APACHESITESDIR/${APACHEOGSITE}.conf"
#    else
#        sed -e "s,OGHDPCDIR,$OGHDPCDIR,g" \
#            "$WORKDIR/ogboot/server/etc/apache.conf.tmpl" > "$path_apache2_confd/$APACHESITESDIR/${APACHEOGSITE}.conf"
#    fi
#    $APACHEENABLEOG
#    if [ $? -ne 0 ]; then
#        errorAndLog "${FUNCNAME}(): config file can't be linked to apache conf, verify your server installation"
#        return 1
#    fi
#    echoAndLog "${FUNCNAME}(): config file created and linked, restarting apache daemon"
#    service="$APACHESERV"
#    $ENABLESERVICE; $STARTSERVICE
#    return 0
#}

####################################################################
####################################################################
####################################################################
####################################################################
####################################################################
####################################################################
####################################################################

#####################################################################
####### Algunas funciones útiles de propósito general:
#####################################################################

# Obtiene la fecha y hora actual en el formato especificado
function getDateTime() {
    date "+%Y%m%d-%H%M%S"
}

# Escribe un mensaje en el archivo de registro y lo muestra por pantalla
function echoAndLog() {
    local DATETIME=$(getDateTime)
    echo "$1"
    echo "$DATETIME;$SSH_CLIENT;$1" >> "$LOG_FILE"
}

# Escribe un mensaje de error en el archivo de registro y lo muestra por pantalla
function errorAndLog() {
    local DATETIME=$(getDateTime)
    echo "ERROR: $1"
    echo "$DATETIME;$SSH_CLIENT;ERROR: $1" >> "$LOG_FILE"
}

# Escribe un mensaje de advertencia en el archivo de registro y lo muestra por pantalla
function warningAndLog() {
    local DATETIME=$(getDateTime)
    echo "Warning: $1"
    echo "$DATETIME;$SSH_CLIENT;Warning: $1" >> "$LOG_FILE"
}

# Hace un backup del fichero pasado por parámetro
# deja un -last y uno para el día
function backupFile()
{
	if [ $# -ne 1 ]; then
		errorAndLog "${FUNCNAME}(): invalid number of parameters"
		exit 1
	fi

	local file="$1"
	local dateymd=`date +%Y%m%d`

	if [ ! -f "$file" ]; then
		warningAndLog "${FUNCNAME}(): file $file doesn't exists"
		return 1
	fi

	echoAndLog "${FUNCNAME}(): making $file backup"

	# realiza una copia de la última configuración como last
	cp -a "$file" "${file}-LAST"

	# si para el día no hay backup lo hace, sino no
	if [ ! -f "${file}-${dateymd}" ]; then
		cp -a "$file" "${file}-${dateymd}"
	fi

	echoAndLog "${FUNCNAME}(): $file backup success"
}

mask2cidr() {
    IFS='.' read -ra ADDR <<< "$1"
    CIDR=0
    for i in "${ADDR[@]}"; do
        CIDR=$((CIDR+$(echo "obase=2; ibase=10; $i" | bc | tr -cd '1' | wc -c)))
    done
    echo $CIDR
}



##########################################################################
################################main######################################

# Sólo ejecutable por usuario root
if [ "$(whoami)" != 'root' ]; then
		echo "ERROR: this program must run under root privileges!!"
		exit 1
fi

globalSetup

echoAndLog "OpenGnsys installation begins at $(date)"

mkdir -p $WORKDIR
pushd $WORKDIR

checkDependencies
install_kea


# Si es necesario, descarga el repositorio de código en directorio temporal
if [ $REMOTE -eq 1 ]; then
	downloadCode $GIT_REPO
	if [ $? -ne 0 ]; then
		errorAndLog "Error while getting code from the repository"
		exit 1
	fi
else
	ln -fs "$(dirname $PROGRAMDIR)" ogboot
fi

create_ogboot_project ${INSTALL_TARGET}
if [ $? -ne 0 ]; then
        errorAndLog "Error while creating skeleton directory!"
        exit 1
fi

# Arbol de directorios de OpenGnsys.
createDirs ${INSTALL_TARGET}
if [ $? -ne 0 ]; then
	errorAndLog "Error while creating directory paths!"
	exit 1
fi

## Compilar código fuente de los servicios de OpenGnsys.
#servicesCompilation
#if [ $? -ne 0 ]; then
#	errorAndLog "Error while compiling OpenGnsys services"
#	exit 1
#fi
#
## Copiar ficheros de servicios OpenGnsys Server.
#copyServerFiles ${INSTALL_TARGET}
#if [ $? -ne 0 ]; then
#	errorAndLog "Error while copying the server files!"
#	exit 1
#fi

# Configuración ejemplo DHCP.
keaDhcpConfigure
if [ $? -ne 0 ]; then
	errorAndLog "Error while copying your dhcp server files!"
	exit 1
fi

# Configuración de TFTP.
tftpConfigure

generate_ipxe_script
if [ $? -ne 0 ]; then
	echo "Error en la generación de scripts IPXE"
	exit 1
fi


mount_NFS
if [ $? -ne 0 ]; then
	echo "Error en el montaje NFS"
	exit 1
fi

# Configuración de Samba.
smbConfigure
if [ $? -ne 0 ]; then
	errorAndLog "Error while configuring Samba server!"
	exit 1
fi


#downloadComposer
#
#runComposer
#install_swagger_ui
## Creando configuración de Apache.
#installWebConsoleApacheConf $INSTALL_TARGET $APACHECFGDIR
#if [ $? -ne 0 ]; then
#	errorAndLog "Error configuring Apache for OpenGnsys Admin"
#	exit 1
#fi

sudo apt-get update
# install_kea
# install_php
# install_composer
# install_symfony
# install_swagger
# Ahora puedes clonar e instalar el componente ogboot
# git clone <URL del repositorio de ogboot>
# cd <directorio de ogboot>
# composer install
