#!/bin/bash
set -e
#set -x
[ -n "$TERM" ] && clear
###
#
# Author: Stéphane HUC
# mail: devs@stephane-huc.net
# gpg:fingerprint: CE2C CF7C AB68 0329 0D20  5F49 6135 D440 4D44 BD58
#
# License: BSD Simplified
#
# Github:
#
# Date: 2021/05/24
#
###
#
# USE: ./deploy
#
###
#
# Need software:
#    - brotli : compression format .br
#    - sshfs + rsync
#    - lftp (solution de repli)
#
###

ROOT="$(dirname "$(readlink -f -- "$0")")"

id='obsd4a'
host='djebeltoubkal.linuxmario.net'
#passwd='TfpLLyC22fbcA3Sm'
port=22

### the directory where your web site files should go
## dir_dist: relative to chroot SSH
dir_dist="/var/www/htdocs/www.openbsd.fr.eu.org/"
dir_local="$ROOT/public/"
dir_mount="$HOME/servers/${host}/"

email="red+bckp-ebnh@huc.fr.eu.org"

rsync_xclud="--exclude=gopher --exclude=gemini"
rsync_opts="--human-readable --progress --stats "


################################################################################
###
##
#   Fonctions
##
###
################################################################################

# process to confirm action
confirm () {
		
	printf '%s\n' "${1}[y|n] "
    read -r response
    case "${response}" in
        # 'o', 'O': Oui and not 0!
        y|Y|o|O|1)  true ;;
        *)          false ;;
    esac

}

# delete all compress files (br, gz)
_del_gz() {	
    cd "${dir_local}" || exit 1
    find . -type f -a \( -name "*.br" -o -name "*.gz" \) -delete
    cd "$ROOT" || exit 1
}

# get rsync status and send mail
get_status() {

    case "$status" in
        0) mssg="Succès" ;;
        1) mssg="Erreur de syntaxe ou d'utilisation" ;;
        2) mssg="Incompatibilité de protocole" ;;
        3) mssg="Erreurs de sélection d'entrée ou de sortie des fichiers ou des répertoires" ;;
        4) mssg="Action demandée non prise en charge : une tentative de manipulation de fichiers 64 bits a été effectuée sur une plate-forme qui ne peut pas les prendre en charge ; ou une option a été spécifiée qui est pris en charge par le client et non par le serveur." ;;
        5) mssg="Erreur de démarrage du protocole client-serveur" ;;
        6) mssg="Le service est incapable d'ajouter au fichier journal" ;;
        10) mssg="Erreur dans le socket I/O" ;;
        11) mssg="Erreur dans le fichier I/O" ;;
        12) mssg="Erreur dans le flux de données du protocole rsync" ;;
        13) mssg="Erreurs de diagnostic du programme" ;;
        14) mssg="Erreur dans le code IPC" ;;
        20) mssg="SIGUSR1 ou SIGINT reçus" ;;
        21) mssg="Une erreur est retournée par waitpid()" ;;
        22) mssg="Erreur lors de l'allocation des mémoires tampons principales" ;;
        23) mssg="Transfert partiel dû à une erreur";;
        24) mssg="Transfert partiel dû à la disparition des fichiers source" ;;
        25) mssg="La limite --max-delete a arrêté les suppressions" ;;
        30) mssg="Délai d'attente pour l'envoi ou la réception de données" ;;
        35) mssg="Délai d'attente pour la connexion du démon" ;;
        *) mssg="Code inconnu !" ;;
    esac

    #[ -z "$IS_CRON" ] && zenotify "Rsync: $choice!" "Rsync: $choice ; status: $mssg!"

    if [ "${status}" -eq 0 ]; then
        mssg="$0::Rsync for ${dir_local}, ended with success!"
    else
        mssg="$0::Rsync Error ${status} on execution for ${dir}, with message: ${mssg}!"
    fi

    logger "$mssg"
    printf '%s\n' "$mssg" | mail -s "$(hostname): Backup Review" $email

    unset mssg status

}

# git process
_git() {
	
	git add . 
	git status
	
	printf '%s\n' "⇒ Tape a message for the commit : "
	read -r mssg 
	
	printf '%s\n' "When you are ready to submit your GPG key…"
	if _press; then
		echo " "
		##printf '\n%s\n' "See the message : ${mssg}"
		##exit
		
		# commit signed message
		git commit -a -S -m "${mssg}" 
	
		# push commit
		git push origin HEAD
	fi
	
	unset mssg
	
}

# Compress all thoses datas files.
_gz() {
    cd "${dir_local}" || exit 1
    find . -not \( -path "./gopher/*" -o -path "./gemini/*" -prune \)  \
		-type f -size +1024c -a \( \
        -name "*.css" -o -name "*.html" -o -name "*.js" -o -name "*.json" \
        -o -name "*.svg" -o -name "*.txt" -o -name "*.xml" \
        \) | while read -r line; do echo "Compress ${line}"; brotli -Z "${line}"; gzip -9 -f < "${line}" > "${line}.gz"; done
        #| while read -r file; do gzip -9 -f -v "${file}"; done
    cd "$ROOT" || exit 1
}

# use lftp 
_lftp() {
    #/usr/local/bin/lftp -e "mirror -e -R ${dir_local} ${dir_dist}; quit" -p $port sftp://${id}@${host}
    lftp -e "set ftp:ssl-allow no; mirror -e -R ${dir_local} ${dir_dist}; quit;" ftp://${id}:${passwd}@${host}
}

main() {
	
	if confirm "Do you want to publish a git commit? "; then
		_git
	fi
	
	if confirm "Do you want to minimize images? "; then
		_minify
		sleep 1
		
		_webp
		sleep 1
	fi
	
	if confirm "Do you want to build articles and publish them? "; then
		hugo --gc
		status="$?"

		if [ "${status}" -eq 0 ]; then
		
			_del_gz
			sleep 1
			_gz
			sleep 1

			if _mount; then
				_rsync
				_umount

			elif confirm "Do you want to try lftp to publish?"; then
				_lftp
			fi
		fi
	fi
}

# call minify script
_minify() {
    /home/zou/Projets/outils/minify.bash "$ROOT/static"
}

# mount remoted fs with sshfs
_mount() {
    [ ! -d "${dir_mount}" ] && mkdir -p "${dir_mount}"
    #[ -d "${dir_mount}" ] && sshfs -C -p $port -o allow_other -o uid=$(id -u $USER) -o gid=$(id -g $USER) ${id}@${host}:${dir_dist} "${dir_mount}"
    [ -d "${dir_mount}" ] && sshfs -C -p $port -o uid=$(id -u $USER) -o gid=$(id -g $USER) ${id}@${host}:${dir_dist} "${dir_mount}"
}

# process press any key
_press() {
	
	read -n 1 -s -r -p "Press any key to continue"
}

# call rsync
_rsync() {

    cd "${dir_local}" || exit
    rsync -av --delete $rsync_xclud $rsync_opts "." "${dir_mount}"
    status="$?"
    get_status
    cd "$ROOT" || exit 1

}

# unmount FS
_umount() {
    fusermount -u "${dir_mount}"
}

# compress image to webp format
_webp() {
	cd "${ROOT}/static" || exit 1
	find . -type f -a \( \
		-name "*.gif" -o -name '*.jpg' -o -name '*.jpeg' -o -name '*.png' \
		\) | while read -r file; do if [ ! -f "${file}.webp" ]; then cwebp "${file}" -exact -lossless -o "${file}.webp"; fi; done
	cd "$ROOT" || exit 1
}

################################################################################
###
##
#   Execution
##
###
################################################################################

main
