#!/bin/bash

#####################################################################
####### Script instalador Ogclient
####### Autor: Luis Gerardo Romero <lguillen@unizar.es>
#####################################################################

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

	# Comprobar si se ha descargado el paquete comprimido (REMOTE=0) o sólo el instalador (REMOTE=1).
	OPENGNSYS_SERVER="opengnsys.es"
	if [ -d "$PROGRAMDIR/../installer" ]; then
		echo REMOTE=0
		REMOTE=0
	else
		echo REMOTE=1
		REMOTE=1
	fi
	BRANCH=$1
	if [[ -z $BRANCH ]]; then
		BRANCH="main"
	fi
	GIT_REPO="ssh://git@ognproject.evlt.uma.es:21987/opengnsys/ogdhcp.git"

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

	# Registro de incidencias.
	OGLOGFILE=$INSTALL_TARGET/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)

    # 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."
}

# Instalar dependencias para Symfony y Swagger
function install_symfony_swagger_dependencies() {
    echoAndLog "Installing Symfony and Swagger dependencies..."
    sudo apt-get update
    sudo apt-get install -y 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
    sudo apt-get install -y composer
    sudo apt-get install -y unzip
    echoAndLog "Symfony and Swagger dependencies installed."
}

# Instalar dependencias para Apache
function install_apache_dependencies() {
    echoAndLog "Installing Apache dependencies..."
    sudo apt-get update
    sudo apt-get install -y apache2 libapache2-mod-php
    echoAndLog "Apache dependencies installed."
}


# Función para instalar los paquetes necesarios para KEA-DHCP
install_kea() {
    sudo apt-get install -y kea-dhcp4-server kea-dhcp6-server
}

# Función para instalar PHP y las extensiones necesarias para Symfony
install_php() {
    sudo apt-get install -y 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
}

# 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 Symfony
install_symfony() {
    composer global require symfony
    echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc
    source ~/.bashrc
}


# 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
}

# Función para instalar el componente ogdhcp
install_ogdhcp() {
    git clone <URL del repositorio de ogdhcp>
    sudo mv ogdhcp /opt/
    cd /opt/ogdhcp
    composer install
}


# 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/config
    mkdir -p $path_opengnsys_base/docs  # Swagger documentation
    mkdir -p $path_opengnsys_base/public
    mkdir -p $path_opengnsys_base/src
    mkdir -p $path_opengnsys_base/templates
    mkdir -p $path_opengnsys_base/var/{cache,log}
    mkdir -p $path_opengnsys_base/vendor
    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=$path_opengnsys_base/var/log
    chmod 600 $LOG_FILE

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


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=( bin \
            config \
            public \
            src \
            templates \
            tests \
            vendor \
            .env \
            composer.json \
            composer.lock \
            phpunit.xml.dist \
            symfony.lock )
    local TARGETS=( bin \
            config \
            public \
            src \
            templates \
            tests \
            vendor \
            .env \
            composer.json \
            composer.lock \
            phpunit.xml.dist \
            symfony.lock )

    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/ogdhcp
    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

    popd
}


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

function getDateTime()
{
	date "+%Y%m%d-%H%M%S"
}

# Escribe a fichero y muestra por pantalla
function echoAndLog()
{
	local DATETIME=`getDateTime`
	echo "$1"
	echo "$DATETIME;$SSH_CLIENT;$1" >> $LOG_FILE
}

# Escribe a fichero y muestra mensaje de error
function errorAndLog()
{
	local DATETIME=`getDateTime`
	echo "ERROR: $1"
	echo "$DATETIME;$SSH_CLIENT;ERROR: $1" >> $LOG_FILE
}

# Escribe a fichero y muestra mensaje de aviso
function warningAndLog()
{
	local DATETIME=`getDateTime`
	echo "Warning: $1"
	echo "$DATETIME;$SSH_CLIENT;Warning: $1" >> $LOG_FILE
}

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


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



# 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)" opengnsys
fi

globalSetup

echoAndLog "OpenGnsys installation begins at $(date)"

mkdir -p $WORKDIR
pushd $WORKDIR

# Arbol de directorios de OpenGnsys.
createDirs ${INSTALL_TARGET}
if [ $? -ne 0 ]; then
	errorAndLog "Error while creating directory paths!"
	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

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

