#!/bin/bash

show_help() {
        echo "Usage: ${0##*/} [check|update|upgrade] [community|supported] (--noreboot|--nopostfix)"
        echo "Updates the grommunio environment including OS"
	echo ""
        echo "Use \`${0##*/} check\`   to see which updates are available for installation."
        echo "Use \`${0##*/} update\`  to update packages without moving to the latest distribution version."
        echo "Use \`${0##*/} upgrade\` to upgrade the system to the latest distribution version."
        echo ""
        echo "Second parameter is      to use either community or supported repositories for specified action."
        echo ""
        echo "Use \`--noreboot\` to not reboot automatically if recommended."
        echo "Use \`--nopostfix\` to not update postfix configuration."
}

make_reboot() {
	echo -e "\n${RED}▶ Reboot initiated.${TXTRST} System is rebooted in 5 seconds."
	sleep 5
	/sbin/shutdown -r now
}

NOREBOOT=0
NOPOSTFIX=0

for ARG in "$@"; do
	case "$ARG" in
		check|update|upgrade)
			OPERATION="$ARG"
			OPERATION_TXT="${ARG^}"
			;;
		community|supported)
			REPO="$ARG"
			;;
		--noreboot)
			NOREBOOT=1
			;;
		--nopostfix)
			NOPOSTFIX=1
			;;
		-h|--help)
			show_help
			exit 0
			;;
		*)
			show_help
			exit 1
			;;
	esac
done

if [ -z "${OPERATION}" ]; then
	echo -e "Error: Operation is required.\n"
	show_help
	exit 1
fi

BLUE="\x1b[36m"
GREEN="\x1b[32m"
RED="\x1b[31m"
YELLOW="\x1b[33m"
TXTRST="\x1b[0m"
LOGFILE="/var/log/grommunio-update.log"

echo -e "${BLUE}                                       _                       __     __
  ___ ________  __ _  __ _  __ _____  (_)__  ______ _____  ___/ /__ _/ /____
 / _ \/ __/ _ \/  ' \/  ' \/ // / _ \/ / _ \/___/ // / _ \/ _  / _ \/ __/ -_)
 \_, /_/  \___/_/_/_/_/_/_/\_,_/_//_/_/\___/    \_,_/ .__/\_,_/\_,_/\__/\__/
/___/                                              /_/${TXTRST}"

exec > >(tee -i ${LOGFILE})
exec 2>&1

FULL_COMMAND_LINE=("$0" "$@")
NOW=$(date "+%a %Y-%m-%d %H:%M:%S %Z")
echo -e "
## This system\t: $(hostname -f)
## Uptime\t: $(uptime | grep -ohe 'up .*' | sed 's/up *//g' | awk -F "," '{ print $1 }')
## Load\t\t: $(uptime | grep -ohe 'load average[s:][: ].*' | awk '{ print "Last Minute: " $3" Last 5 Minutes: "$4" Last 15 Minutes: "$5 }')
## IP Address\t: $(ip addr | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | xargs)
## Executed\t: ${FULL_COMMAND_LINE[*]}
## Start\t: ${NOW}"
echo -ne "## Operation\t: ${OPERATION_TXT}\n"

if [ -f /etc/os-release ]; then
	. /etc/os-release
else
	echo "The file /etc/os-release was not found. The distribution cannot be identified."
	exit 1
fi

case ${ID} in
	debian|ubuntu)
		PKG_MANAGER="apt"
		if [[ ${OPERATION} == "upgrade" ]]; then
			UPDATE_CMD="apt-get update -y && apt-get dist-upgrade -y"
		elif [[ ${OPERATION} == "update" ]]; then
			UPDATE_CMD="apt-get update -y && apt-get upgrade -y"
		else
			UPDATE_CMD="apt-get update -y && apt-get upgrade -u -s"
		fi
		;;
	centos|rhel|rocky|almalinux)
		PKG_MANAGER="yum"
		if [[ ${OPERATION} == "upgrade" || ${OPERATION} == "update" ]]; then
			UPDATE_CMD="yum clean expire-cache -y && yum update -y"
			command -v dnf >/dev/null 2>&1 && { PKG_MANAGER="yum"; UPDATE_CMD="dnf upgrade --refresh -y"; }
		else
			UPDATE_CMD="yum clean expire-cache -y && yum check-update -y"
			command -v dnf >/dev/null 2>&1 && { PKG_MANAGER="yum"; UPDATE_CMD="dnf check-update -y"; }
		fi
		;;
	opensuse*|sles)
		PKG_MANAGER="zypper"
		if [[ ${OPERATION} == "upgrade" ]]; then
			UPDATE_CMD="zypper ref && zypper dup -y"
		elif [[ ${OPERATION} == "update" ]]; then
			UPDATE_CMD="zypper ref && zypper up -y"
		else
			UPDATE_CMD="zypper ref && zypper lu"
		fi
		;;
	grommunio*)
		PKG_MANAGER="zypper"
		if [[ ${OPERATION} == "upgrade" ]]; then
			UPDATE_CMD="zypper ref && zypper dup -y"
		elif [[ ${OPERATION} == "update" ]]; then
			UPDATE_CMD="zypper ref && zypper up -y"
		else
			UPDATE_CMD="zypper ref && zypper lu --allow-vendor-change"
		fi
		;;
	*)
		echo "Distribution '${ID}' is not supported. Please check available distributions at https://download.grommunio.com"
		exit 1
		;;
esac

echo -en "\n${BLUE}▶${TXTRST} Starting ${OPERATION_TXT} (${UPDATE_CMD})."
echo -e "\n${BLUE}▶${TXTRST} on repository ${REPO}."
if [ -n "${REPO}" ]; then
	/usr/sbin/grommunio-repo "${REPO}"
fi
eval "${UPDATE_CMD}"

UPDATE_EXIT_STATUS=$?

NOW=$(date "+%a %Y-%m-%d %H:%M:%S %Z")
if [ ${UPDATE_EXIT_STATUS} -eq 0 ]; then
	echo -ne "\n${GREEN}▶${TXTRST} ${OPERATION_TXT} completed successfully."
else
	echo -ne "\n${RED}▶${TXTRST} ${OPERATION_TXT} failed with exit status ${UPDATE_EXIT_STATUS}, please check the log ${LOGFILE}\n"
	echo -ne "\n\n## End ${OPERATION_TXT}\t:${NOW}"
	echo
	exit ${UPDATE_EXIT_STATUS}
fi

if [[ ${NOPOSTFIX} -eq 0 ]]; then
	echo -ne "\n${BLUE}▶${TXTRST} Updating postfix configuration with new maps if exist"
	/usr/sbin/grommunio-postfix
fi

if [[ ${OPERATION} == "update" ]] || [[ ${OPERATION} == "upgrade" ]]; then
	if [ "${PKG_MANAGER}" == "zypper" ]; then
		echo -ne "\n${BLUE}▶${TXTRST} Running post-update/upgrade checks"
		systemctl daemon-reload
		if [[ "$(systemctl is-active redis@grommunio)" != "active" ]]; then
			systemctl enable redis@grommunio
			systemctl restart redis@grommunio
		fi
		if [[ ! -e /etc/php8/fpm/php-fpm.conf ]]; then
			mv /etc/php8/fpm/php-fpm.conf.default /etc/php8/fpm/php-fpm.conf
			systemctl enable php-fpm
			systemctl restart php-fpm
		fi
	fi
	if [[ "$(/usr/sbin/gromox-dbop -U | wc -l)" != "1" ]]; then
		systemctl try-restart gromox-http gromox-zcore grommunio-admin-api
	fi
	if [[ "$(systemctl is-active postfix)" != "active" ]]; then
		postconf -e smtpd_discard_ehlo_keywords=chunking
	fi
fi

echo -ne "\n${BLUE}▶${TXTRST} Checking for pending service restart or reboot"
if [ "${PKG_MANAGER}" == "zypper" ] || [ "${PKG_MANAGER}" == "apt" ]; then
	if [ -f /var/run/reboot-needed ] || [ -f /var/run/reboot-required ]; then
		if [[ ${NOREBOOT} -eq 1 ]] || [[ ${OPERATION} == "check" ]]; then
			echo -e "\n${YELLOW}▶ Reboot required.${TXTRST} Kernel upgrade waiting for activation. Please restart the system for the changes to take effect."
		else
			make_reboot
		fi
		echo -e "\n\n## End ${OPERATION_TXT}\t: ${NOW}"
		echo
		exit 3
	else
		if [ "${PKG_MANAGER}" == "zypper" ]; then
			zypper ps -sss | while read -r SERVICE; do
			echo -ne "\n## Restarting service ${SERVICE} after update: "
			systemctl restart "${SERVICE}"
			echo -ne "... done"
		done
		if [[ $(zypper ps -sss | wc -l) -gt 0 ]]; then
			if [[ ${NOREBOOT} -eq 1 ]] || [[ ${OPERATION} == "check" ]]; then
				echo -e "\n${YELLOW}▶ Reboot required.${TXTRST} Not all services could be restarted. Please restart the system for the changes to take effect."
			else
				make_reboot
			fi
		fi
		fi
		echo -e "\n\n## End ${OPERATION_TXT}\t: ${NOW}"
		echo
		exit ${UPDATE_EXIT_STATUS}
	fi
elif [ "${PKG_MANAGER}" == "yum" ] || [ "${PKG_MANAGER}" == "dnf" ]; then
	CURRENT_KERNEL=$(uname -r)
	LATEST_KERNEL=$(rpm -q --last kernel | head -n 1 | awk '{ print $1 }' | sed 's/kernel-//')

	if [ "${CURRENT_KERNEL}" != "${LATEST_KERNEL}" ]; then
		if [[ ${NOREBOOT} -eq 1 ]]; then
			echo -e "\n${YELLOW}▶ Reboot required.${TXTRST} Kernel upgrade waiting for activation. Please restart the system for the changes to take effect."
		else
			make_reboot
		fi
		echo -e "\n\n## End ${OPERATION_TXT}\t: ${NOW}"
		echo
		exit 3
	else
		echo -e "\n\n## End ${OPERATION_TXT}\t: ${NOW}"
		echo
		exit ${UPDATE_EXIT_STATUS}
	fi
fi
