#!/usr/bin/env bash

ENABLED=yes
[[ ${ENABLED} == "yes" ]] || exit 0
DEBUGMODE=no

SOURCE=/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null  || exit 0
SOURCE=/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null  || exit 0
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/server; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null

debug_mode "$0" "$@"

PATH_UBPILE="/opt/ubpile"
UBPILE_CONF_JSON="${PATH_UBPILE}/conf/config.json"
UBPILE_CONF_JSON_TEMPLATE="${PATH_UBPILE}/sample_conf/config.json"
PATH_HAPROXY_UBPILE_CONF="/etc/haproxy/haproxy-ubpile.cfg"

## Использовать приложение UBPile
##   UBPILE=primary|worker|disable|clean
##     primary	# Выступать в роли главного сервера управляющего всеми 'Worker'
##     worker	# Исполнитель заданий приходящих от сервера 'Primary'
##     disable	# Отключить
##     clean	# Очистить БД и вернуть настройки по умолчанию. После процедуры очистки установится UBPILE=disable
##   UBPILE[secret_key|base_app_url|...]=<value>
##     secretkey	# При настройке нескольких серверов все ваши серверы должны иметь один и тот же секретный ключ. Любая случайно сгенерированная строка подойдет
##     base_app_url	# Полный URL-адрес, включая http порт, если он нестандартный. Это используется в электронных письмах для создания URL-адресов с самостоятельными ссылками
##     email_from	# Адрес электронной почты, который будет использоваться в качестве адреса "От" при отправке уведомлений
##     smtp_hostname	# Имя хоста вашего SMTP-сервера для отправки почты. Так-же это может быть `127.0.0.1` или `localhost`
##     debug_level	# Уровень детализации в журналах отладки. Он варьируется от 1 (очень тихо) до 10 (очень громко). Значение по умолчанию — 4
##     job_memory_max	# Максимальное ограничение памяти по умолчанию для каждого задания, по умолчанию: 1073741824 (1Гб)
##     
##     server_comm_use_hostnames # Разрешить серверам подключаться друг к другу по именам хостов, полезно с меняющимися IP адресами. Значения: *false, true
##     web_direct_connect	# Разрешить веб-интерфейсу прямое подключение к главному серверу, полезно при использовании нескольких резервных серверов 
##				# или балансировщик нагрузки или обратного прокси. Значения: *false, true
##     web_socket_use_hostnames	# Разрешить веб-интерфейсу подключаться к внутренним серверам, используя их имена хостов, а не IP-адреса. Значения: *false, true
##     				# Это свойство вступает в силу только в том случае, если web_direct_connect=true
##     WebServer.http_port	# Номер порта http веб-сервера для пользовательского интерфейса. По умолчанию: 9012
##     WebServer.https		# Включить HTTPS, чтобы пользовательский интерфейс был зашифрован SSL. Значения: *false, true
##     WebServer.https_port	# Номер порта https веб-сервера для пользовательского интерфейса. По умолчанию: 9013
##     ...			# Могут использоваться любые переменные конфигурационного файла config.json
## UBPILE[secret_key]="4a6ed27e0434490028ff63b11f12fb7c"
## UBPILE[base_app_url]="http://localhost:80"
## UBPILE[web_direct_connect]="true"
exec_01_ubpile(){
    clean_db(){
	[[ ${PATH_UBPILE}/data ]] && rm -rdf ${PATH_UBPILE}/data
    }
    [[ -d ${PATH_UBPILE} ]] || return 0
    [[ ! -f ${UBPILE_CONF_JSON} || $(stat --printf="%s" ${UBPILE_CONF_JSON} 2>/dev/null) -lt 10 ]] && cp -f ${UBPILE_CONF_JSON_TEMPLATE} ${UBPILE_CONF_JSON}
    
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || COMMAND="set="
    local PARAM="$@"
    if [[ -n ${PARAM} ]]; then
	local UBPILE=
	declare -A UBPILE
	[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
    fi
    if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#UBPILE[@]} != 0 ]]; then
	local STRING_ARG_CONF=
        if [[ -f ${UBPILE_CONF_JSON} ]]; then
	    for NAME_ARG_CONF in "${!UBPILE[@]}"; do
	        if [[ ${NAME_ARG_CONF} != 0 ]] && [[ ${UBPILE[${NAME_ARG_CONF}]} =~ ^([[:digit:]]*|true|false)$ ]]; then
	    	    STRING_ARG_CONF+=".${NAME_ARG_CONF} = ${UBPILE[${NAME_ARG_CONF}]} | "
	    	elif [[ ${NAME_ARG_CONF} != 0 ]]; then
	    	    STRING_ARG_CONF+=".${NAME_ARG_CONF} = \"${UBPILE[${NAME_ARG_CONF}]}\" | "
	    	fi
    	    done
    	    [[ -n ${STRING_ARG_CONF} ]] && echo -E "$(jq "${STRING_ARG_CONF%|*}" ${UBPILE_CONF_JSON})" > ${UBPILE_CONF_JSON}
	fi
	# Удалить ключ из системной конфигурации
	[[ -n ${UBPILE[secret_key]} ]] && sed "/UBPILE\[secret_key\]=/d" -i ${SYSCONF}/server
    
	if [[ ${UBPILE[0]} == "clean" ]]; then
	    ubconfig set [server] UBPILE=disable
	    clean_db
	elif [[ ${UBPILE[0]} == "primary" ]]; then
	    chmod o-rwx ${PATH_UBPILE}
	    #systemctl --quiet is-active ubpile.service &>/dev/null || 
	    ${PATH_UBPILE}/bin/control.sh setup
	    systemctl --quiet enable ubpile.service &>/dev/null
	    systemctl --quiet restart ubpile.service &>/dev/null
	elif [[ ${UBPILE[0]} == "worker" ]]; then
	    chmod o-rwx ${PATH_UBPILE}
	    clean_db
	    systemctl --quiet enable ubpile.service &>/dev/null
	    systemctl --quiet restart ubpile.service &>/dev/null
	elif [[ ${UBPILE[0]} == "disable" ]]; then
	    systemctl --quiet stop ubpile.service haproxy-ubpile.service &>/dev/null
	    systemctl --quiet disable ubpile.service haproxy-ubpile.service &>/dev/null
	else
	    echo "INFO: you need restart UBPile: systemctl restart ubpile.service"
	    #systemctl --quiet is-active ubpile.service &>/dev/null && systemctl --quiet restart ubpile.service &>/dev/null
	fi
    elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
	if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
	    NAME_VAR=${BASH_REMATCH[1]}
	    TEMPLATE_VALUE=$(jq ".${NAME_VAR}" ${UBPILE_CONF_JSON_TEMPLATE})
	    echo -E "$(jq ".${NAME_VAR} = ${TEMPLATE_VALUE}" ${UBPILE_CONF_JSON})" > ${UBPILE_CONF_JSON}
	    echo "INFO: you need restart UBPile: systemctl restart ubpile.service"
	    #systemctl --quiet is-active ubpile.service &>/dev/null && systemctl --quiet restart ubpile.service &>/dev/null
	else
	    systemctl --quiet stop ubpile.service haproxy-ubpile.service &>/dev/null
	    systemctl --quiet disable ubpile.service haproxy-ubpile.service &>/dev/null
	fi
    fi
    message_motd
}

## Использовать для UBPile преднастроенный обратный прокси, разместив приложение на указанном порту
##   UBPILE_REVERSE_PROXY=enable|disable|<http_port>
##     enable           # Только включить автозапуск и запустить сервис haproxy-ubpile.service
##     disable          # Выключить и отключить автозапуск сервис haproxy-ubpile.service
##     <http_port>      # Настроить http порт, включить автозапуск и запустить сервис haproxy-ubpile.service
##                      # Если требуется настройка SSL, то необходимо полученный сертификат вручную прописать в файле конфигурации /etc/haproxy/haproxy-ubpile.cfg
## UBPILE_REVERSE_PROXY_PORT=80
exec_02_reverse_proxy_port(){
    [[ -d ${PATH_UBPILE} ]] || return 0
    local STRING_ARG_CONF=
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || COMMAND="set="
    local PARAM="$@"
    if [[ -n ${PARAM} ]]; then
	local UBPILE_REVERSE_PROXY_PORT=
	[[ ${PARAM%%=*} =~ [!\$%\&()*+,/\;\<\=\>?\^\{|\}~] ]] || eval "${PARAM%%=*}=\${PARAM#*=}"
    fi
    if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ -n ${UBPILE_REVERSE_PROXY_PORT} ]]; then
	if [[ ${UBPILE_REVERSE_PROXY_PORT} == @(disable|no) ]]; then
	    systemctl --quiet stop haproxy-ubpile.service &>/dev/null
	    systemctl --quiet disable haproxy-ubpile.service &>/dev/null
	elif [[ ${UBPILE_REVERSE_PROXY_PORT} == @(enable|yes) ]]; then
	    UBPILE_PORT="$(sed -En '/^\s*frontend http/,/^\s*backend/{s/^\s*bind.*:([[:digit:]]*).*/\1/p}' ${PATH_HAPROXY_UBPILE_CONF})"
	    [[ $(declare -p UBPILE 2>/dev/null) =~ "declare -A" && -n ${UBPILE[web_direct_connect]} ]] || { ubconfig set [server] UBPILE[web_direct_connect]="true"; RESTART_UBPILE=yes; }
	    [[ $(declare -p UBPILE 2>/dev/null) =~ "declare -A" && -n ${UBPILE[base_app_url]} ]] || { ubconfig set [server] UBPILE[base_app_url]="http://localhost:${UBPILE_PORT:-80}"; RESTART_UBPILE=yes; }
	    systemctl --quiet enable haproxy-ubpile.service &>/dev/null
	    systemctl --quiet restart haproxy-ubpile.service &>/dev/null
	elif [[ ${UBPILE_REVERSE_PROXY_PORT} =~ ^[[:digit:]]*$ ]]; then
	    # Пропишем порт в конфиге haproxy
	    sed -E "/^\s*frontend http/,/^\s*backend/s/^\s*bind.*/    bind        \*:${UBPILE_REVERSE_PROXY_PORT}/" -i ${PATH_HAPROXY_UBPILE_CONF}
	    # Если параметры не заданы в конфиге, то зададим
	    ubconfig set [server] UBPILE[web_direct_connect]="true"
	    ubconfig set [server] UBPILE[base_app_url]="http://localhost:${UBPILE_REVERSE_PROXY_PORT:-3012}"
	    RESTART_UBPILE=yes
	    systemctl --quiet enable haproxy-ubpile.service &>/dev/null
	    systemctl --quiet restart haproxy-ubpile.service &>/dev/null
	fi
    elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
	[[ -f ${UBPILE_CONF_JSON} ]] && UBPILE_PORT=$(jq '.WebServer.http_port' ${UBPILE_CONF_JSON})
	[[ $(declare -p UBPILE 2>/dev/null) =~ "declare -A" && -n ${UBPILE[web_direct_connect]} ]] && { ubconfig remove [server] UBPILE[web_direct_connect]; RESTART_UBPILE=yes; }
	[[ $(declare -p UBPILE 2>/dev/null) =~ "declare -A" && -n ${UBPILE[base_app_url]} ]] && { ubconfig remove [server] UBPILE[base_app_url]; RESTART_UBPILE=yes; }
	systemctl --quiet stop haproxy-ubpile.service &>/dev/null
	systemctl --quiet disable haproxy-ubpile.service &>/dev/null
    fi
    [[ -n ${RESTART_UBPILE} ]] && systemctl --quiet is-active ubpile.service &>/dev/null && systemctl --quiet restart ubpile.service &>/dev/null
    message_motd
}

message_motd(){
    [[ -d ${PATH_UBPILE} ]] || return 0
    local UBPILE_RUN="/run/ubpile"
    PC_HOSTNAME="$(hostname -f)"
    PC_IP="$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')"
    install -dm0755 ${UBPILE_RUN}
    [[ -f ${UBPILE_CONF_JSON} ]] && UBPILE_PORT=$(jq '.WebServer.http_port' ${UBPILE_CONF_JSON})
    systemctl --quiet is-active haproxy-ubpile.service &>/dev/null && UBPILE_PORT="$(sed -En '/^\s*frontend http/,/^\s*backend/{s/^\s*bind.*:([[:digit:]]*).*/\1/p}' ${PATH_HAPROXY_UBPILE_CONF})"
    systemctl --quiet is-active ubpile.service &>/dev/null && ln -snf active.motd ${UBPILE_RUN}/motd || ln -snf inactive.motd ${UBPILE_RUN}/motd
    echo -e "Веб-консоль UBPile: http://${PC_HOSTNAME}:${UBPILE_PORT:-3012}/ или http://${PC_IP:-127.0.0.1}:${UBPILE_PORT:-3012}/\n" > ${UBPILE_RUN}/active.motd
    echo -e "Запустить веб-консоль UBPile: systemctl enable --now ubpile.service\n" > ${UBPILE_RUN}/inactive.motd
}

################
##### MAIN #####
################
    
    # Если файл подключен как ресурс с функциями, то выйти
    return 0 2>/dev/null && return 0
    if [[ -z $@ ]]; then
        while read -ru3 FUNCTION; do
            $"${FUNCTION##* }"
        done 3< <(declare -F | grep "declare -f exec_")
    else
	while [[ $# -gt 0 ]]; do
	    declare -f ${1} &>/dev/null && FUNCTION+="; ${1}" && shift || { FUNCTION+=" '${1}'" && shift; }
	done
	eval ${FUNCTION#*; }
    fi
