#!/bin/bash
set -eu
### --help Info: настройка конфигов uwsgi emperor
### --help Usage:
### --help Example:
. /opt/fox_utils/crab_sys.sh
sys::arg_parse "$@"

declare NGINX_ENABLED EVA_DEPLOY_TYPE SLA MEMORY_LIMIT_GB
source /opt/CONFIG

# Конфигурацию собираем в /tmp/:
#   uwsgi-emperor.ini - император
#   uwsgi-vassals/ - где император ищет вассалов(*.ini,*.xml,*.json, ...)
#     add vassal config - spawn vassal server
#     touch/modify vassal config - reload vassal server
#     remove vassal config - stop vassal server
#   uwsgi-vassal-config.ini - Общая конфигурация всех вассалов
#     Включает:
#       uwsgi-vassal-scaling.ini - параметры скейлинга, если есть
#       uwsgi-vassal-config-custom.ini - кастом параметры, если есть копируем из
#         /mnt/shared/config/uwsgi-vassal-config-custom.ini
# Конфигурация деплоя лежит в /opt/bin/configs/uwsgi/...
# Конфигурация App лежит в /opt/App/uwsgi-...
# Custom Конфигурация App лежит в /opt/App/custom/uwsgi-...
#
# /tmp/ <- /opt/bin/configs/uwsgi/
#   uwsgi-emperor.ini <-
#     vassal-include:
#       /tmp/uwsgi-vassal-config.ini <-
#         vars:
#           $eva_app_processes = 2
#           $eva_app_offload_threads = 1
#       [/tmp/uwsgi-vassal-scaling.ini]
#       [uwsgi-vassal-config-custom.ini] <- [/mnt/shared/config/uwsgi-vassal-config.ini]
#   uwsgi-vassals/
#     eva-app.ini <- custom or
#     eva-app-job.ini <- custom or
#     eva-app-socketio.ini
#     eva-webdav.ini
#     [eva-converter.ini] - not cloud
#     [nginx.ini] - if enabled
#

clear_old_config() {
	rm -rf --one-file-system \
		/tmp/{uwsgi-vassals,uwsgi-emperor.ini,uwsgi-vassal-config.ini} \
		/tmp/{uwsgi-vassal-scaling.ini,uwsgi-vassal-config-custom.ini}
	return 0
}

make_scaling_config() {
	local eva_app_processes='' eva_app_offload_threads='' socketio_listen=''
	if [[ $EVA_DEPLOY_TYPE = cloud* && ${SLA:-} ]]; then
		echo "Configure scaling for SLA: $SLA" >&2
		read -r eva_app_processes eva_app_offload_threads \
			<<<"$(/opt/fox_acrm/deploy/provision.py \
			--sla "$SLA" \
			--print-value uwsgi.processes uwsgi.offload)"
	else
		read -r eva_app_processes eva_app_offload_threads \
			<<<"$(/opt/fox_acrm/deploy/provision.py \
			--memory-limit-gb "${MEMORY_LIMIT_GB:-8}" \
			--print-value uwsgi.processes uwsgi.offload)"
	fi
	# Хак: socketio в некоторых случаях лагает при рестарте. Помогает увеличение очереди
	# Пример ошибки:
	# u_offload_transfer_prepare()/connect():
	#   Resource temporarily unavailable [core/offload.c line 113]
	# error routing request to uwsgi server /tmp/soketio-eva-app.sock
	# Выставляем динамически, т.к. в vm может быть лимит
	if [[ -f /proc/sys/net/core/somaxconn ]]; then
		socketio_listen=$(</proc/sys/net/core/somaxconn)
		if [[ $socketio_listen -ge 1024 ]]; then
			socketio_listen=1024
		fi
	fi
	cat >/tmp/uwsgi-vassal-scaling.ini <<EOF
[uwsgi]
${eva_app_processes:+set-placeholder = eva_app_processes=$eva_app_processes}
${eva_app_offload_threads:+set-placeholder = eva_app_offload_threads=$eva_app_offload_threads}
${socketio_listen:+set-placeholder = socketio_listen=$socketio_listen}
EOF
	return 0
}

make_common_configs() {
	cp /opt/bin/configs/uwsgi/uwsgi-emperor.ini /tmp/uwsgi-emperor.ini
	cp /opt/bin/configs/uwsgi/uwsgi-vassal-config.ini /tmp/uwsgi-vassal-config.ini
	# Set proper uwsgi umask
	sed -i -E "s/^umask *=.*/umask = $(umask)/" /tmp/uwsgi-vassal-config.ini
	make_scaling_config
	if [[ -f /mnt/shared/config/uwsgi-vassal-config-custom.ini ]]; then
		cp /mnt/shared/config/uwsgi-vassal-config-custom.ini \
			/tmp/uwsgi-vassal-config-custom.ini
	fi
	return 0
}

make_vassals_config() {
	# local config="$1" custom_config="${2:-}" name
	# name="${config##*/}"
	local name="$1" config custom_config
	config="/opt/bin/configs/uwsgi/uwsgi-vassals/$name.ini"
	custom_config="/mnt/shared/config/uwsgi-vassals/$name.ini"

	if [[ $custom_config && -s $custom_config ]]; then
		echo "Setup uwsgi service (!custom) from $custom_config" >&2
		cp "$custom_config" "/tmp/uwsgi-vassals/$name.ini"
	elif [[ $custom_config && -z $custom_config ]]; then
		echo "Skip uwsgi service due empty config $custom_config" >&2
	else
		echo "Setup uwsgi service from $config" >&2
		cp "$config" "/tmp/uwsgi-vassals/$name.ini"
	fi
	return 0
}

make_vassals_configs() {
	mkdir /tmp/uwsgi-vassals
	make_vassals_config eva-app
	make_vassals_config eva-app-socketio
	make_vassals_config eva-app-job
	make_vassals_config eva-webdav
	if [[ ! $EVA_DEPLOY_TYPE =~ ^(cloud.*)$ ]]; then
		make_vassals_config eva-converter
	fi
	if [[ ! $EVA_DEPLOY_TYPE =~ ^(cloud.*)$ && ${NGINX_ENABLED:-TRUE} = TRUE ]]; then
		make_vassals_config nginx
	fi
	return 0
}

main() {
	clear_old_config
	make_common_configs
	make_vassals_configs
	return 0
}

main
exit 0
