#!/bin/bash

# XXX pb arret des services retiré

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

cd $(dirname $0)
ORGA_DIR="$(basename "$(pwd)")"
TIMESTAMP=YES
TMPL_PROXY_COMPOSE="${KAZ_COMP_DIR}/proxy/docker-compose.tmpl.yml"
TMPL_TRAEFIK_COMPOSE="${KAZ_COMP_DIR}/traefik/docker-compose.tmpl.yml"
ORGA_LIST="${KAZ_CONF_DIR}/container-orga.list"
LIST=""

STAGE_DEFAULT=true
STAGE_CREATE=
STAGE_INIT=

usage(){
    echo "Usage: $0 [-h] [-l] [+/-paheko] [-/+cloud [-/+collabora}]] [+/-agora] [+/-wiki] [+/-wp] [+/-pod] [x{G/M/k}] OrgaName"
    echo "    -h|--help         : this help"
    echo "    -l|--list         : list service"

    echo "    --create          : only create (before start)"
    echo "    --init            : only init (after start)"
    
    echo "    +/- paheko        : on/off paheko"
    echo "    +/- cloud         : on/off cloud"
    echo "    +/- coll*         : on/off collabora"
    echo "    +/- matter*|agora : on/off agora"
    echo "    +/- wiki          : on/off wiki"
    echo "    +/- wp|word*      : on/off wp"
    echo "    +/- casto*|pod    : on/off castopod"
    echo "    x[GMk]            : set quota"
    echo "    OrgaName          : name must contain a-z0-9_\-"
}

for ARG in "$@"; do
    case "${ARG}" in
	'-h' | '--help' )
	    usage
	    exit 0;;
	'-l' | '--list' )
	;;
	'--create' )
	    STAGE_DEFAULT=
	    STAGE_CREATE=true
	    if [[ -n "${STAGE_INIT}" ]]; then
		usage
		echo "    Incompatible options (--create --init)"
		exit 1
	    fi
	;;
	'--init' )
	    STAGE_DEFAULT=
	    STAGE_INIT=true
	    if [[ -n "${STAGE_CREATE}" ]]; then
		usage
		echo "    Incompatible options (--create --init)"
		exit 1
	    fi
	;;
	'-'* )
	;;
	'+'* )
	;;
	[.0-9]*[GMk] )
	;;
	* )
	    if [[ "${ORGA_DIR}" = "orgaTmpl" ]]; then
		if [[ "${ARG}" =~ ^[a-z0-9_\-]+$ ]]; then
		    printKazMsg "create ${ARG}"
		    ORGA_PATH="${KAZ_COMP_DIR}/${ARG}-orga"
		    mkdir -p "${ORGA_PATH}"
		    cd "${ORGA_PATH}"
		    ORGA_DIR="$(basename "$(pwd)")"
		    ln -sf ../../config/dockers.env .env
		    ln -sf ../../config/orgaTmpl/orga-gen.sh
		    ln -sf ../../config/orgaTmpl/orga-rm.sh
		    ln -sf ../../config/orgaTmpl/reload.sh
		else
		    printKazError "Name must contains only a-z0-9_\-"
		    usage
		    exit 1
		fi
	    else
		if [[ "${ARG}-orga" !=  "${ORGA_DIR}" ]]; then
		    printKazError "Can't cross config ${ARG}-orga with ${ORGA_DIR}"
		    usage
		    exit 1
		fi
	    fi
	    ;;
    esac
done

if [[ "${ORGA_DIR}" = "orgaTmpl" ]]
then
    printKazError "You must give orga name"
    usage
    exit 1
fi

if [[ "${ORGA_DIR}" != *"-orga" ]]
then
    printKazError "it's not an orga dir"
    exit
fi
ORGA=${ORGA_DIR%-orga}

if [[ -z "${ORGA}" ]]
then
    printKazError "it's not an orga dir"
    exit
fi

# default values
flagInCompose(){
    # $1 filename (docker-compose.yml)
    # $2 service name
    # $3 default value
    if [[ ! -f "$1" ]]
    then
	echo "$3"
    else
	if grep -q "$2" docker-compose.yml 
	then
	    echo on
	else
	    echo off
	fi
    fi
}

export cloud=$(flagInCompose docker-compose.yml cloud: off)
export collabora=$(flagInCompose docker-compose.yml collabora: off)
export agora=$(flagInCompose docker-compose.yml agora: off)
export wiki=$(flagInCompose docker-compose.yml dokuwiki: off)
export wp=$(flagInCompose docker-compose.yml wordpress: off)
export castopod=$(flagInCompose docker-compose.yml castopod: off)
export db="off"
export services="off"
export paheko=$([[ -f usePaheko  ]] && echo "on" || echo "off")
export quota=10G
if [[ -f docker-compose.yml ]]; then
    if grep -q "storage_opt" docker-compose.yml 
    then
	quota=$(grep "storage_opt" docker-compose.yml | cut -d : -f 2 | tail -n 1)
    fi
fi

DBaInitialiser=""
INITCMD2="--install"


for ARG in "$@"; do
    case "${ARG}" in
	'-show' )
	    for i in cloud collabora agora wiki wp castopod db; do
		echo "${i}=${!i}"
	    done
	    exit;;
	'-h' | '--help' )
	    usage
	    exit 1
	    ;;
	'-l' | '--list' )
	    LIST="list"
	    ;;
	'-time'* )
	    TIMESTAMP=YES
	    ;;
	'-paheko'* )
	    paheko="off"
	    ;;
	'-cloud' )
	    cloud="off"
	    collabora="off"
	    ;;
	'-coll'* | '-offi'* )
	    collabora="off"
	    ;;
	'-matter'* | '-agora')
	    agora="off"
	    ;;
	'-wiki' )
	    wiki="off"
	    ;;
	'-wp' | '-word'* )
	    wp="off"
	    ;;
        '-pod' | '-casto'* )
            castopod="off"
            ;;
	'+paheko' )
	    paheko="on"
	    ;;	    
	'+cloud' )
	    cloud="on"
        DBaInitialiser="$DBaInitialiser cloud"
		INITCMD2="$INITCMD2 -cloud"
	    ;;
	'+coll'* | '+offi'* )
	    collabora="on"
		INITCMD2="$INITCMD2 -office"
	    ;;
	'+matter'* | '+agora' )
	    agora="on"
	    DBaInitialiser="$DBaInitialiser agora"
		INITCMD2="$INITCMD2 -agora"
	    ;;
	'+wiki' )
	    wiki="on"
	    ;;
	'+wp' | '+word'* )
	    wp="on"
	    DBaInitialiser="$DBaInitialiser wp"
		INITCMD2="$INITCMD2 -wp"
	    ;;
	'+pod' | '+casto'* )
	    castopod="on"
	    DBaInitialiser="$DBaInitialiser castopod"
		INITCMD2="$INITCMD2 -pod"
	    ;;
	[.0-9]*[GMk] )
	    quota="${ARG}"
	    ;;
    esac
done

if [ "${cloud}" = "on" -o "${agora}" = "on" -o "${wp}" = "on" -o "${castopod}" = "on" ]
then
    db="on"
fi
if [ "${db}" = "on" -o "${wiki}" = "on" ]
then
    services="on"
fi

. "${DOCKERS_ENV}"
ORGA_FLAG=${ORGA_DIR//-/_}
DOMAIN_AREA="{{${ORGA_FLAG}\n"
ADD_DOMAIN=""
DEL_DOMAIN=""

listServ () {
    for serv in $(getAvailableServices); do
	if [[ "${!serv}" == "on" ]]; then
	    echo "${serv}"
	fi
    done
}

if [[ -n "${LIST}" ]] ; then
    listServ
    exit
fi

if [[ "${paheko}"   = "on" ]]; then
    touch usePaheko
    mkdir -p /var/lib/docker/volumes/paheko_assoUsers/_data/${ORGA}
    chown www-data:www-data /var/lib/docker/volumes/paheko_assoUsers/_data/${ORGA} -R
    ADD_DOMAIN+="${ORGA}-${pahekoHost} "
else
    rm -f usePaheko
    DEL_DOMAIN+="${ORGA}-${pahekoHost} "
fi
if [[ "${cloud}"      = "on" ]]; then
    DOMAIN_AREA+="      - ${ORGA}-\${nextcloudServName}:${ORGA}-\${cloudHost}.\${domain}\n"
    ADD_DOMAIN+="${ORGA}-${cloudHost} "
else
    DEL_DOMAIN+="${ORGA}-${cloudHost} "
fi
if [[ "${collabora}"  = "on" ]]; then
    DOMAIN_AREA+="      - ${ORGA}-\${officeServName}:${ORGA}-\${officeHost}.\${domain}\n"
    ADD_DOMAIN+="${ORGA}-${officeHost} "
else
    DEL_DOMAIN+="${ORGA}-${officeHost} "
fi
if [[ "${agora}"      = "on" ]]; then
    DOMAIN_AREA+="      - ${ORGA}-\${mattermostServName}:${ORGA}-\${matterHost}.\${domain}\n"
    ADD_DOMAIN+="${ORGA}-${matterHost} "
else
    DEL_DOMAIN+="${ORGA}-${matterHost} "
fi
if [[ "${wiki}"       = "on" ]]; then
    DOMAIN_AREA+="      - ${ORGA}-\${dokuwikiServName}:${ORGA}-\${dokuwikiHost}.\${domain}\n"
    ADD_DOMAIN+="${ORGA}-${dokuwikiHost} "
else
    DEL_DOMAIN+="${ORGA}-${dokuwikiHost} "
fi
if [[ "${wp}"         = "on" ]]; then
    DOMAIN_AREA+="      - ${ORGA}-\${wordpressServName}:${ORGA}-\${wordpressHost}.\${domain}\n"
    ADD_DOMAIN+="${ORGA}-${wordpressHost} "
else
    DEL_DOMAIN+="${ORGA}-${wordpressHost} "
fi
if [[ "${castopod}"         = "on" ]]; then
    DOMAIN_AREA+="      - ${ORGA}-\${castopodServName}:${ORGA}-\${castopodHost}.\${domain}\n"
    ADD_DOMAIN+="${ORGA}-${castopodHost} "
else
    DEL_DOMAIN+="${ORGA}-${castopodHost} "
fi
DOMAIN_AREA+="}}\n"

if [[ -n "${STAGE_DEFAULT}${STAGE_CREATE}" ]]; then
    if [[ -f "${TMPL_TRAEFIK_COMPOSE}" ]]; then
	# ########## update traefik/docker-compose.tmpl.yml
	printKazMsg "Update ${TMPL_TRAEFIK_COMPOSE}"
	if grep -q "^{{${ORGA_FLAG}" "${TMPL_TRAEFIK_COMPOSE}" 2> /dev/null ; then
	    sed -i -e "/^{{${ORGA_FLAG}/,/^}}/d" "${TMPL_TRAEFIK_COMPOSE}"
	fi
	# use net
	sed "s/^#### END ORGA USE_NET/{{${ORGA_FLAG}\n      - ${ORGA}Net\n}}\n#### END ORGA USE_NET/" -i "${TMPL_TRAEFIK_COMPOSE}"
	# def net
	sed "s/^#### END ORGA DEF_NET/{{${ORGA_FLAG}\n  ${ORGA}Net:\n    external: true\n    name: ${ORGA}-orgaNet\n}}\n#### END ORGA DEF_NET/" -i "${TMPL_TRAEFIK_COMPOSE}"
    fi
    if [[ -f "${TMPL_PROXY_COMPOSE}" ]]; then
	# ########## update proxy/docker-compose.tmpl.yml
	printKazMsg "Update ${TMPL_PROXY_COMPOSE}"
	if grep -q "^{{${ORGA_FLAG}" "${TMPL_PROXY_COMPOSE}" 2> /dev/null ; then
	    sed -i -e "/^{{${ORGA_FLAG}/,/^}}/d" "${TMPL_PROXY_COMPOSE}"
	fi
	# domaine
    sed "s/^#### END ORGA HOST/${DOMAIN_AREA}#### END ORGA HOST/" -i "${TMPL_PROXY_COMPOSE}"
    # use net
    sed "s/^#### END ORGA USE_NET/{{${ORGA_FLAG}\n      - ${ORGA}Net\n}}\n#### END ORGA USE_NET/" -i "${TMPL_PROXY_COMPOSE}"
    # def net
    sed "s/^#### END ORGA DEF_NET/{{${ORGA_FLAG}\n  ${ORGA}Net:\n    external: true\n    name: ${ORGA}-orgaNet\n}}\n#### END ORGA DEF_NET/" -i "${TMPL_PROXY_COMPOSE}"
    fi
fi

if [[ -n "${STAGE_DEFAULT}${STAGE_CREATE}" ]]; then
    # ########## update DNS
    printKazMsg "Update DNS"
    ${KAZ_BIN_DIR}/dns.sh add ${ADD_DOMAIN}
    ${KAZ_BIN_DIR}/dns.sh del ${DEL_DOMAIN}
fi

update() {
    (
	# $1 = template
	# $2 = target
	if [ "${TIMESTAMP}" == "YES" ]; then
	    echo "# Generated by $(pwd)$(basename $0)"
	    echo "# à partir du modèle $1"
	    echo "#" $(date "+%x %X")
	    echo
	fi
	FOREIGN_WP=$(grep " ${ORGA};" "${KAZ_CONF_PROXY_DIR}/wp_kaz_map" 2>/dev/null | \
			 sed "s/\([^ ]*\) ${ORGA};/ \|\| Host(\`\1\`)/" | tr -d "\r\n")
	FOREIGN_NC=$(grep " ${ORGA};" "${KAZ_CONF_PROXY_DIR}/cloud_kaz_map" 2>/dev/null | \
			 sed "s/\([^ ]*\) ${ORGA};/ \|\| Host(\`\1\`)/" | tr -d "\r\n")
	FOREIGN_DW=$(grep " ${ORGA};" "${KAZ_CONF_PROXY_DIR}/wiki_kaz_map" 2>/dev/null | \
			 sed "s/\([^ ]*\) ${ORGA};/ \|\| Host(\`\1\`)/" | tr -d "\r\n")
	FOREIGN_POD=$(grep " ${ORGA};" "${KAZ_CONF_PROXY_DIR}/pod_kaz_map" 2>/dev/null | \
			 sed "s/\([^ ]*\) ${ORGA};/ \|\| Host(\`\1\`)/" | tr -d "\r\n")
	awk '
	       	 BEGIN     {cp=1}
		 /#}}/     {cp=1 ; next};
		 /#{{on/   {cp=1; next};
		 /#{{off/  {cp=0; next};
		 match($0, /#{{[a-zA-Z0-9_]+/)  {cp=(ENVIRON[substr($0,RSTART+3,RLENGTH)] == "on"); next};
		 {if (cp) print $0};' $1 | sed \
					       -e "/^[ \t]*$/d"\
					       -e "/^[ ]*#.*$/d"\
					       -e "s/{{FOREIGN_WP}}/${FOREIGN_WP}/"\
					       -e "s/{{FOREIGN_NC}}/${FOREIGN_NC}/"\
					       -e "s/{{FOREIGN_DW}}/${FOREIGN_DW}/"\
					       -e "s/{{FOREIGN_POD}}/${FOREIGN_POD}/"\
					       -e "s|\${orga}|${ORGA}-|g"
    ) > "$2"
    sed "s/storage_opt:.*/storage_opt: ${quota}/g" -i "$2"
}

if [[ -n "${STAGE_DEFAULT}${STAGE_CREATE}" ]]; then
    # ########## update ${ORGA_DIR}/docker-compose.tmpl.yml
    printKazMsg "update docker-compose.yml ${ORGA}"
    update ${KAZ_CONF_DIR}/orgaTmpl/docker-compose.yml docker-compose.yml
    printKazMsg "Service enabled:"
    for service in $(listServ) ; do
	printKazMsg "  * ${service}"
    done
fi

if [[ -n "${STAGE_DEFAULT}${STAGE_CREATE}" ]]; then
    # ########## update ${ORGA_DIR}/init-volume.sh
    update ${KAZ_CONF_DIR}/orgaTmpl/init-volume.sh init-volume.sh
    chmod a+x init-volume.sh

    ln -sf ../../config/orgaTmpl/orga-gen.sh
    ln -sf ../../config/orgaTmpl/orga-rm.sh
    ln -sf ../../config/orgaTmpl/init-paheko.sh    
    ln -sf ../../config/orgaTmpl/initdb.d/
    ln -sf ../../config/orgaTmpl/app/
    ln -sf ../../config/orgaTmpl/wiki-conf/
    ln -sf ../../config/orgaTmpl/reload.sh
    ln -sf ../../config/orgaTmpl/init-db.sh
fi

if [[ -n "${STAGE_DEFAULT}${STAGE_CREATE}" ]]; then
    # ########## update ${DOCKERS_ENV}
    if ! grep -q "proxy_orga=" .env 2> /dev/null
    then
	echo "proxy_orga=on"  >> .env
    fi

    if ! grep -q "proxy_${ORGA_FLAG}=" .env 2> /dev/null
    then
	echo "proxy_${ORGA_FLAG}=off"  >> .env
    fi
    touch "${ORGA_LIST}"
    if ! grep -qx "${ORGA}-orga" "${ORGA_LIST}" 2> /dev/null
    then
	echo "${ORGA}-orga"  >> "${ORGA_LIST}"
    fi
fi

if [[ -n "${STAGE_DEFAULT}${STAGE_CREATE}" ]]; then
    # ########## create volume
    ./init-volume.sh
fi

if [[ -n "${STAGE_CREATE}" ]]; then
    # ########## start docker
    docker-compose up -d
fi
if [[ -n "${STAGE_DEFAULT}" ]]; then
    # ########## start docker proxy
    ${KAZ_BIN_DIR}/container.sh start ${ORGA}-orga
fi

if [[ -n "${STAGE_DEFAULT}" ]]; then
    # ########## stop ${DOCKERS_ENV}
    for service in $("${KAZ_BIN_DIR}/kazList.sh" service disable ${ORGA}-orga); do
	DockerServName=
	case "${service}" in
	    agora)
		DockerServName="${ORGA}-${mattermostServName}"
		;;
	    paheko)
		continue
		;;		
	    cloud)
		DockerServName="${ORGA}-${nextcloudServName}"
		;;
	    collabora)
		DockerServName="${ORGA}-${officeServName}"
		;;
	    wiki)
		DockerServName="${ORGA}-${dokuwikiServName}"
		;;
	    wp)
		DockerServName="${ORGA}-${wordpressServName}"
		;;
	esac
	if checkDockerRunning "${DockerServName}" "${service}"; then
	    printKazMsg "  - stop ${service}"
	    docker rm -f "${DockerServName}" 2>/dev/null
	fi
    done
fi

if [[ -n "${STAGE_DEFAULT}${STAGE_INIT}" ]]; then
	[ -z "$DBaInitialiser" ] || ./init-db.sh $DBaInitialiser
    # ########## init services
    [[ "${paheko}"  = "on" ]] && ./init-paheko.sh
	# initCmd="--install"
    # # XXX risque d'écraser user DB
    # [[ "${cloud}"  = "on" ]] && initCmd="$initCmd -cloud"
    # # XXX risque d'écraser user DB
    # [[ "${wp}"     = "on" ]] && initCmd="$initCmd -wp"
    # [[ "${wiki}"   = "on" ]] && initCmd="$initCmd -wiki"
    # # XXX risque d'écraser user DB
    # [[ "${agora}"  = "on" ]] && initCmd="$initCmd -agora"
    # [[ "${castopod}"  = "on" ]] && initCmd="$initCmd -castopod"

	# on initialise que si il y a au moins un truc à initialiser
    [[ "${INITCMD2}" != "--install" ]] && ${KAZ_BIN_DIR}/gestContainers.sh $INITCMD2 "${ORGA}"
fi

if [[ -n "${STAGE_DEFAULT}" ]]; then
    # ########## update status web page
    ${KAZ_COMP_DIR}/web/web-gen.sh
fi