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

declare DOMAIN=
declare NGINX_SCHEME=
declare NGINX_USE_CERTBOT=
declare ADMIN_EMAIL=

declare NGINX_ENABLED
source /opt/CONFIG

# NGINX_ACCOUNT_SCHEME='port'

prepare(){
	# rm -f /etc/nginx/sites-enabled/default
	if [ ! -f /mnt/tmp/etc/nginx/dh4096.pem ]; then
		mkdir -p /mnt/tmp/etc/nginx/
		openssl dhparam -dsaparam -out /mnt/tmp/etc/nginx/dh4096.pem 4096
	fi
	return 0
}


build_selfsigned_if_not_exists(){
	if [ -f "/etc/nginx/ssl/${DOMAIN}.crt" ]; then
		# Это может быть клиентский сертификат, не имеем права его трогать
		return 0
	fi

	(
		cd /etc/nginx/ssl/
		echo "Не найден сертификат для домена ${DOMAIN}. Генерируем самоподписной"
		/opt/bin/self-signed-cert-ctl "$DOMAIN"
	)

	rm -f /etc/nginx/conf.d/${DOMAIN}.conf
	return 0
}

check_selfsigned_rootcert(){
	local ln_ca ln_pem
	if [ ! -f "/etc/nginx/ssl/rootCA.pem" ]; then
		echo "Самоподписной сертификат не использовался"
		return 0
	fi
	# Проверяем, что root сертификат прописан в файлы
	grep -F -x -f \
		"/etc/nginx/ssl/rootCA.pem" \
		/etc/ssl/certs/ca-certificates.crt >/tmp/_nginx_configure.crt.$$
	ln_ca="$(cat /tmp/_nginx_configure.crt.$$ | grep -v '^---' | sort | uniq | wc -l || true )"
	rm -f "/tmp/_nginx_configure.crt.$$"
	ln_pem="$(cat /etc/nginx/ssl/rootCA.pem | grep -v '^---' | sort | uniq | wc -l )"
	if [ "$ln_ca" != "$ln_pem" ]; then
		echo "Прописываем самоподписной сертификат"
		cat "/etc/nginx/ssl/rootCA.pem" \
			>> /etc/ssl/certs/ca-certificates.crt
		cat "/etc/nginx/ssl/rootCA.pem" \
			>> /usr/local/lib/python3.8/dist-packages/certifi/cacert.pem
	fi
	return 0
}

check_corp_rootcert(){
	local ln_ca ln_pem
	if [ ! -f "/etc/nginx/ssl/corp_rootCA.pem" ]; then
		echo "Корпоративный корневой сертификат не указан."
		echo "Если он необходим, сохраните его в /etc/nginx/ssl/corp_rootCA.pem"
		return 0
	fi
	sed -i 's/\r$//' /etc/nginx/ssl/corp_rootCA.pem
	# Simple Validate
	grep -Fxqe '-----BEGIN CERTIFICATE-----' /etc/nginx/ssl/corp_rootCA.pem
	grep -F -x -f \
		"/etc/nginx/ssl/corp_rootCA.pem" \
		/etc/ssl/certs/ca-certificates.crt >/tmp/_nginx_configure.crt.$$
	ln_ca="$(cat /tmp/_nginx_configure.crt.$$ | grep -v '^---' | sort | uniq | wc -l || true )"
	rm -f "/tmp/_nginx_configure.crt.$$"
	ln_pem="$(cat /etc/nginx/ssl/corp_rootCA.pem | grep -v '^---' | sort | uniq | wc -l )"
	if [ "$ln_ca" != "$ln_pem" ]; then
		echo "Прописываем корпоративный корневой сертификат в систему"
		cat "/etc/nginx/ssl/corp_rootCA.pem" \
			>> /etc/ssl/certs/ca-certificates.crt
		cat "/etc/nginx/ssl/corp_rootCA.pem" \
			>> /usr/local/lib/python3.8/dist-packages/certifi/cacert.pem
	fi
	return 0
}

localhost_domain(){
	echo "Прописываем 127.0.0.1 $DOMAIN в /etc/hosts"
	if ! grep -q "127.0.0.1 $DOMAIN" /etc/hosts; then
		echo "127.0.0.1 $DOMAIN" >> /etc/hosts || true
		# Для read-only docker-контейнеров должен использоваться параметр -h
	fi
	return 0
}

build_scheme_domain(){
	# TODO: перенести в eva_configure, это настройки не nginx
	echo "Настраиваем работу на домене ${DOMAIN} ..."
	# configure
	cp -a /opt/bin/templates/eva-app.conf /mnt/tmp/etc/nginx/conf.d/eva-app.conf
	# Пробуем на одном домене
	sed -i "s/@@@eva_domain%%%/${DOMAIN}/g" /mnt/tmp/etc/nginx/conf.d/eva-app.conf
	sed -i "s/@@@account_domain%%%/${DOMAIN}/g" /mnt/tmp/etc/nginx/conf.d/eva-app.conf

	# Описание полей https://bcrm.carbonsoft.ru/project/Document/DOC-004285
	# Версия без SSO

	local conf
	for conf in /opt/eva-app/custom/config.py; do
		/opt/fox_utils/crab_conf set ORG_DOMAIN "$DOMAIN" "$conf"
		/opt/fox_utils/crab_conf set APP_NAME "${DOMAIN%%.*}" "$conf"
		/opt/fox_utils/crab_conf set APP_FQDN "$DOMAIN" "$conf"
		/opt/fox_utils/crab_conf set AUTH_SERVER_URL "https://$DOMAIN" "$conf"
		/opt/fox_utils/crab_conf set AUTH_SESSION_COOKIE_DOMAIN "$DOMAIN" "$conf"
		/opt/fox_utils/crab_conf set HOSTNAME_FQDN "$DOMAIN" "$conf"
		/opt/fox_utils/crab_conf set ORG_NAME "${DOMAIN%%.*}" "$conf"
	done

	echo "${DOMAIN%%.*}" > /opt/eva-app/custom/org_name

	# echo "Перезагружаем сервисы..."
	# /etc/init.d/account restart || true
	# /etc/init.d/eva-app restart || true
	# Нестабильно, пока не делаем
	# Нужно только для быстрой смены домена
	# need sleep /etc/init.d/postgresql restart || true
	# На случай смены домена - вызываем sync
	# Сейчас это приведет к дублированию скоупов, но список eva-app не виден в web пользователю
	# echo "Синхронизируем базу пользователей..."
	# (
	# 	cd /opt/eva-app
	# 	python3 manage.py shell 'from cmf.include import *; models.CmfPerson.sync_accounts()' || true
	# )
	return 0
}

check_certbot(){
	echo "Проверяем сертификат LetsEncrypt"
	if ! certbot --nginx -d "$DOMAIN" -m "$ADMIN_EMAIL" -n --agree-tos; then
		echo "Ошибка получения сертификата Lets Encrypt!"
		echo "Возможно, домен $DOMAIN недоступен из сети интернет или указан неверно."
		echo "Если домен недоступен из интернета (например, доступен только в интранете)"
		echo "то нужно отключить опцию NGINX_USE_CERTBOT и добавить сертификат вручную"
		return 0
	fi
	ln -sf /etc/letsencrypt/live/${DOMAIN}/fullchain.pem \
		/etc/nginx/ssl/${DOMAIN}.crt
	ln -sf /etc/letsencrypt/live/${DOMAIN}/privkey.pem \
		/etc/nginx/ssl/${DOMAIN}.key
	return 0
}

main(){
	if [ "${NGINX_ENABLED:-TRUE}" != 'TRUE' ]; then
		echo "Сервис nginx отключен, пропускаем процедуру его конфигурации"
		exit 0
	fi
	prepare
	build_selfsigned_if_not_exists
	check_selfsigned_rootcert
	check_corp_rootcert
	localhost_domain
	build_scheme_domain
	if [ "${NGINX_USE_CERTBOT:-}" = "1" ]; then
		check_certbot
		# вызываем еще раз, т.к. certbot портит конфиг
		build_scheme_domain
	fi
	return 0
}

main
exit 0
