#!/bin/bash

#Ki: François
#Kan: 2021
#Koi: gestion dockers

# 15/01/2025: Dernière modif by fab: ne pas redémarrer Traefik en cas de créaio d'orga 
# Did : 13 fevrier 2025 modif des save en postgres et mysql
# Did : ajout des sauvegardes de mobilizon et mattermost en postgres

# 20/04/2025
# Did : Ajout des sauvegardes de peertube dans les services generaux


# En cas d'absence de postfix, il faut lancer :
# docker network create postfix_mailNet

# démare/arrête un compose
# sauvegarde la base de données d'un compose
# met à jours les paramètres de configuration du mandataire (proxy)

KAZ_ROOT=$(cd "$(dirname $0)/.."; pwd)
. "${KAZ_ROOT}/bin/.commonFunctions.sh"
setKazVars

cd "${KAZ_BIN_DIR}"
PATH_SAUVE="/home/sauve/"
export SIMU=""

declare -a availableComposesNoNeedMail availableMailComposes availableComposesNeedMail availableProxyComposes availableOrga
availableComposesNoNeedMail=($(getList "${KAZ_CONF_DIR}/container-withoutMail.list"))
availableMailComposes=($(getList "${KAZ_CONF_DIR}/container-mail.list"))
availableComposesNeedMail=($(getList "${KAZ_CONF_DIR}/container-withMail.list"))
availableProxyComposes=($(getList "${KAZ_CONF_DIR}/container-proxy.list"))
availableOrga=($(getList "${KAZ_CONF_DIR}/container-orga.list"))
availableComposesNeedMail+=( "${availableOrga[@]}" )

knownedComposes+=( ${availableMailComposes[@]} )
knownedComposes+=( ${availableProxyComposes[@]} )
knownedComposes+=( ${availableComposesNoNeedMail[@]} )
knownedComposes+=( ${availableComposesNeedMail[@]} )

usage () {
    echo "Usage: $0 [-n] {status|start|stop|save} [compose]..."
    echo "    -n         : simulation"
    echo "    status     : docker-compose status (default all compose available)"
    echo "    start      : start composes (default all compose validate)"
    echo "    stop       : stop composes (default all compose enable)"
    echo "    save       : save all known database"
    echo "    [compose]  : in ${knownedComposes[@]}"
    exit 1
}

doCompose () {
    # $1 dans ("up -d" "down")
    # $2 nom du répertoire du compose
    echo "compose: $1 $2"
    ${SIMU} cd "${KAZ_COMP_DIR}/$2"
    if [ ! -h .env ] ; then
	echo "create .env in $2"
	${SIMU} ln -fs ../../config/dockers.env .env
    fi
    ${SIMU} docker-compose $1
}

doComposes () {
    # $1 dans ("up -d" "down")
    # $2+ nom des répertoires des composes
    cmd=$1
    shift
    for compose in $@ ; do
	doCompose "${cmd}" ${compose}
    done
}

updateProxy () {
    # $1 dans ("on" "off")
    # $2 nom des répertoires des composes
    cmd=$1
    shift
    echo "update proxy ${cmd}: $@"
    date=$(date "+%x %X")
    for compose in $@ ; do
	composeFlag=${compose//-/_}
	entry="proxy_${composeFlag}="
	newline="${entry}${cmd}	# update by $(basename $0) at ${date}"
	if ! grep -q "proxy_${composeFlag}=" "${DOCKERS_ENV}" 2> /dev/null ; then
	    if [[ -n "${SIMU}" ]] ; then
		echo "${newline} >> ${DOCKERS_ENV}"
	    else
		echo "${newline}"  >> "${DOCKERS_ENV}"
	    fi
	else
	    ${SIMU} sed -i \
		    -e "s|${entry}.*|${newline}|g" \
		    "${DOCKERS_ENV}"
	fi
    done
	for item in "${availableProxyComposes[@]}"; do
    	${SIMU} ${KAZ_COMP_DIR}/${item}/proxy-gen.sh
    done
}

saveDB () {
    containerName=$1
    userName=$2
    userPass=$3
    dbName=$4
    backName=$5
    backDbType=$6
    #on utilise mysqldump (v=10.5) et mariadb-dump (v>=11.4) et pgdump pour être certain d'avoir un dump. L'une des 3 lignes fera une erreur
    # on teste si le backup est pour mysql ou postgres
    if [[ -n "${SIMU}" ]] ; then
	${SIMU} "[ ${backDbType} = mysql ] && docker exec ${containerName} mysqldump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz"
	${SIMU} "[ ${backDbType} = mysql ] && docker exec ${containerName} mariadb-dump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz"
	${SIMU} "[ ${backDbType} = postgres ] && docker exec ${containerName} pg_dumpall --username=${userName} | gzip >${PATH_SAUVE}/${backName}.pgdump.sql.gz"
    else
	[ ${backDbType} = mysql ] && docker exec ${containerName} mysqldump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz
	[ ${backDbType} = mysql ] && docker exec ${containerName} mariadb-dump --user=${userName} --password=${userPass} ${dbName} | gzip > $PATH_SAUVE${backName}.sql.gz
	[ ${backDbType} = postgres ] && docker exec ${containerName} pg_dumpall --username=${userName} | gzip >${PATH_SAUVE}/${backName}.pgdump.sql.gz
    fi
}

declare -a enableComposesNoNeedMail enableMailComposes enableComposesNeedMail enableProxyComposes

enableComposesNoNeedMail=()
enableMailComposes=()
enableComposesNeedMail=()
enableProxyComposes=()

startComposes () {
    ./kazDockerNet.sh add ${enableComposesNoNeedMail[@]} ${enableProxyComposes[@]} ${enableMailComposes[@]} ${enableComposesNeedMail[@]} 
	[ ${#enableComposesNeedMail[@]} -ne 0 ] && [[ ! "${enableMailComposes[@]}" =~ "postfix" ]] && ./kazDockerNet.sh add postfix
	[[ "${enableComposesNeedMail[@]}" =~ "paheko" ]] && ${SIMU} ${KAZ_COMP_DIR}/paheko/paheko-gen.sh
    doComposes "up -d" ${enableComposesNoNeedMail[@]}
    doComposes "up -d" ${enableMailComposes[@]}
    doComposes "up -d" ${enableComposesNeedMail[@]}
    updateProxy "on" ${enableComposesNoNeedMail[@]} ${enableComposesNeedMail[@]}
    #fab le 15/01/25: on ne redémarre plus le proxy avec container.sh
    #doComposes "up -d" ${enableProxyComposes[@]}
	for item in "${enableProxyComposes[@]}"; do
    	[[ -x "${KAZ_COMP_DIR}/${item}/reload.sh" ]] && ${SIMU} "${KAZ_COMP_DIR}/${item}/reload.sh"
	done
    if grep -q  "^.s*proxy_web.s*=.s*on" "${DOCKERS_ENV}" 2> /dev/null ; then
	${SIMU} ${KAZ_COMP_DIR}/web/web-gen.sh
    fi
}

stopComposes () {
    updateProxy "off" ${enableComposesNoNeedMail[@]} ${enableComposesNeedMail[@]}
    doComposes "down" ${enableProxyComposes[@]}
    doComposes "down" ${enableComposesNeedMail[@]}
    doComposes "down" ${enableMailComposes[@]}
    doComposes "down" ${enableComposesNoNeedMail[@]}
    if grep -q  "^.s*proxy_web.s*=.s*on" "${DOCKERS_ENV}" 2> /dev/null ; then
	${SIMU} ${KAZ_COMP_DIR}/web/web-gen.sh
    fi
}

statusComposes () {
    ${KAZ_ROOT}/bin/kazList.sh compose status ${enableMailComposes[@]} ${enableProxyComposes[@]} ${enableComposesNoNeedMail[@]} ${enableComposesNeedMail[@]}
}

saveComposes () {
    . "${DOCKERS_ENV}"

    savedComposes+=( ${enableMailComposes[@]} )
    savedComposes+=( ${enableProxyComposes[@]} )
    savedComposes+=( ${enableComposesNoNeedMail[@]} )
    savedComposes+=( ${enableComposesNeedMail[@]} )
    
    for compose in ${savedComposes[@]}
    do
	case "${compose}" in
	    jirafeau)
	    # rien à faire (fichiers)
	    ;;
	    ethercalc)
	    #inutile car le backup de /var/lib/docker/volumes/ethercalc_calcDB/_data/dump.rdb est suffisant
	    ;;
	    sympa)
       		echo "save sympa"
		. $KAZ_KEY_DIR/env-sympaDB
		saveDB ${sympaDBName} "${DB_MYSQL_USER}" "${DB_MYSQL_PASSWORD}" "${DB_MYSQL_DATABASE}" sympa mysql
		;;
	    web)
		# rien à faire (fichiers)
		;;
	    etherpad)
		echo "save pad"
		. $KAZ_KEY_DIR/env-etherpadDB
		saveDB ${etherpadDBName} "${DB_MYSQL_USER}" "${DB_MYSQL_PASSWORD}" "${DB_MYSQL_DATABASE}" etherpad mysql
		;;
	    framadate)
		echo "save date"
		. $KAZ_KEY_DIR/env-framadateDB
		saveDB ${framadateDBName} "${DB_MYSQL_USER}" "${DB_MYSQL_PASSWORD}" "${DB_MYSQL_DATABASE}" framadate mysql
		;;
	    cloud)
		echo "save cloud"
		. $KAZ_KEY_DIR/env-nextcloudDB
		saveDB ${nextcloudDBName} "${DB_MYSQL_USER}" "${DB_MYSQL_PASSWORD}" "${DB_MYSQL_DATABASE}" nextcloud mysql
		;;
	    paheko)
		# rien à faire (fichiers)
		;;		
	    mattermost)
		echo "save mattermost"
		. $KAZ_KEY_DIR/env-mattermostDB
		saveDB matterPG "${DB_POSTGRES_USER}" "${DB_POSTGRES_PASSWORD}" "${DB_POSTGRES_DB}" mattermost postgres
		;;
	    mobilizon)
		echo "save mobilizon"
		. $KAZ_KEY_DIR/env-mobilizonDB
		saveDB ${mobilizonDBName} "${DB_POSTGRES_USER}" "${DB_POSTGRES_PASSWORD}" "${DB_POSTGRES_DB}" mobilizon postgres
		;;
	    peertube)
		echo "save peertube"
		. $KAZ_KEY_DIR/env-peertubeDB
		saveDB ${peertubeDBName} "${DB_POSTGRES_USER}" "${DB_POSTGRES_PASSWORD}" "${DB_PEERTUBE_DB_HOSTNAME}" peertube postgres
		;;
	    mastodon)
		echo "save mastodon"
		. $KAZ_KEY_DIR/env-mastodonDB
		saveDB ${mastodonDBName} "${DB_POSTGRES_USER}" "${DB_POSTGRES_PASSWORD}" "${DB_POSTGRES_DB}" mastodon postgres
		;;
	    roundcube)
		echo "save roundcube"
		. $KAZ_KEY_DIR/env-roundcubeDB
		saveDB ${roundcubeDBName} "${DB_MYSQL_USER}" "${DB_MYSQL_PASSWORD}" "${DB_MYSQL_DATABASE}" roundcube mysql
		;;	
	    vaultwarden)
		echo "save vaultwarden"
		. $KAZ_KEY_DIR/env-vaultwardenDB
		saveDB ${vaultwardenDBName} "${DB_MYSQL_USER}" "${DB_MYSQL_PASSWORD}" "${DB_MYSQL_DATABASE}" vaultwarden mysql
		;;
	    dokuwiki)
		# rien à faire (fichiers)
		;;
	    *-orga)
		ORGA=${compose%-orga}
		echo "save ${ORGA}"		
		if grep -q "cloud:" "${KAZ_COMP_DIR}/${compose}/docker-compose.yml" 2> /dev/null ; then
		    echo "    => cloud"
			. $KAZ_KEY_DIR/orgas/$ORGA/env-nextcloudDB
		    saveDB "${ORGA}-DB" "${MYSQL_USER}" "${MYSQL_PASSWORD}" "${MYSQL_DATABASE}" "${ORGA}-cloud" mysql
		fi
		if grep -q "agora:" "${KAZ_COMP_DIR}/${compose}/docker-compose.yml" 2> /dev/null ; then
		    echo "    => mattermost"
			. $KAZ_KEY_DIR/orgas/$ORGA/env-mattermostDB
			saveDB "${ORGA}-DB" "${MYSQL_USER}" "${MYSQL_PASSWORD}" "${MYSQL_DATABASE}" "${ORGA}-mattermost" mysql
		fi
		if grep -q "wordpress:" "${KAZ_COMP_DIR}/${compose}/docker-compose.yml" 2> /dev/null ; then
		    echo "    => wordpress"
			. $KAZ_KEY_DIR/orgas/$ORGA/env-wpDB
		    saveDB "${ORGA}-DB" "${MYSQL_USER}" "${MYSQL_PASSWORD}" "${MYSQL_DATABASE}" "${ORGA}-wordpress" mysql
		fi
		if grep -q "spip:" "${KAZ_COMP_DIR}/${compose}/docker-compose.yml" 2> /dev/null ; then
		    echo "    => spip"
			. $KAZ_KEY_DIR/orgas/$ORGA/env-spipDB
		    saveDB "${ORGA}-DB" "${MYSQL_USER}" "${MYSQL_PASSWORD}" "${MYSQL_DATABASE}" "${ORGA}-spip" mysql
		fi
		;;
	esac
    done
}

if [ "$#" -eq 0 ] ; then
    usage
fi

if [ "$1" == "-h" ] ; then
    usage
    shift
fi

if [ "$1" == "-n" ] ; then
    export SIMU=echo
    shift
fi

DCK_CMD=""
SAVE_CMD=""
case "$1" in
    start)
	DCK_CMD="startComposes"
	shift
	;;
    
    stop)
	DCK_CMD="stopComposes"
	shift
	;;

    save)
	SAVE_CMD="saveComposes"
	shift
	;;

    status)
	DCK_CMD="statusComposes"
	shift
	;;
    *)
	usage
	;;
esac

if [ $# -eq 0 ] ; then
    enableComposesNoNeedMail=("${availableComposesNoNeedMail[@]}")
    enableMailComposes=("${availableMailComposes[@]}")
    enableComposesNeedMail=("${availableComposesNeedMail[@]}")
    enableProxyComposes=("${availableProxyComposes[@]}")
else
    if [ "${DCK_CMD}" = "startComposes" ] ; then
	enableProxyComposes=("${availableProxyComposes[@]}")
    fi
fi

for compose in $*
do
    compose=${compose%/}
    if [[ ! " ${knownedComposes[@]} " =~ " ${compose} " ]]; then
	declare -a subst
	subst=()
	for item in "${knownedComposes[@]}"; do
	    [[ "${item}" =~ "${compose}" ]] && subst+=(${item})
	done
	if [ "${subst}" = "" ] ; then
	    echo
	    echo "Unknown compose: ${RED}${BOLD}${compose}${NC} not in ${YELLOW}${BOLD}${knownedComposes[*]}${NC}"
	    echo
	    exit 1
	else
	    echo "substitute compose: ${YELLOW}${BOLD}${compose} => ${subst[@]}${NC}"
	fi
    fi
    for item in "${availableMailComposes[@]}"; do
	[[ "${item}" =~ "${compose}" ]] && enableMailComposes+=("${item}")
    done
    for item in "${availableProxyComposes[@]}"; do
	[[ "${item}" =~ "${compose}" ]] && enableProxyComposes=("${item}")
    done
    for item in "${availableComposesNoNeedMail[@]}"; do
	[[ "${item}" =~ "${compose}" ]] && enableComposesNoNeedMail+=("${item}")
    done
    for item in "${availableComposesNeedMail[@]}"; do
	[[ "${item}" =~ "${compose}" ]] && enableComposesNeedMail+=("${item}")
    done
done

[[ ! -z "${DCK_CMD}" ]] && "${DCK_CMD}" && exit 0

[[ ! -z "${SAVE_CMD}" ]] && "${SAVE_CMD}" && exit 0

exit 1
