#!/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
}

# openSUSE Leap >= 16 refuses to boot on CPUs below the x86_64-v2 baseline
# ("Fatal glibc error: CPU does not support x86-64-v2"). Check before migrating.
cpu_supports_x86_64_v2() {
	local flags f
	flags=$(grep -m1 '^flags' /proc/cpuinfo)
	for f in cx16 sse4_1 sse4_2 popcnt; do
		grep -qw "$f" <<<"$flags" || return 1
	done
	return 0
}

# A kernel/udev upgrade can change predictable NIC names (e.g. eth0 -> ens192),
# which cuts off the network after reboot because the interface config is keyed
# to the old name. Pin each active physical ethernet NIC to its current name by
# MAC (a systemd .link) so the name survives the upgrade and config keeps working.
pin_interface_names() {
	local path iface mac link
	for path in /sys/class/net/*; do
		iface="${path##*/}"
		[ -e "${path}/device" ] || continue
		[ "$(cat "${path}/type" 2>/dev/null)" = "1" ] || continue
		case "${iface}" in lo|veth*|docker*|br-*|virbr*|bond*|tap*|tun*|vnet*|*.*) continue ;; esac
		mac=$(cat "${path}/address" 2>/dev/null)
		[[ "${mac}" =~ ^[0-9a-fA-F:]{17}$ ]] || continue
		link="/etc/systemd/network/10-grommunio-pin-${iface}.link"
		[ -e "${link}" ] && continue
		mkdir -p /etc/systemd/network
		printf '[Match]\nMACAddress=%s\n\n[Link]\nName=%s\n' "${mac}" "${iface}" > "${link}"
		echo -e "  ${BLUE}pinning NIC ${iface} (${mac}) so the upgrade cannot rename it${TXTRST}"
	done
}

# Determine the next openSUSE Leap release to migrate to: the lowest stable
# version newer than the running one, but only if grommunio actually ships
# packages for it. Results are returned via globals (the function must be called
# directly, not in a $(...) subshell, so they propagate): DETECTED_TARGET holds
# the version (e.g. 16.0) or is empty; TARGET_DETECT_FAILED=1 means detection
# could not run (no curl/jq or no network), so the caller can tell "up to date"
# apart from "could not check".
detect_target_leap() {
	local cur="${VERSION_ID}" cur_major="${VERSION_ID%%.*}" target="" api
	DETECTED_TARGET=""
	TARGET_DETECT_FAILED=0
	if ! command -v curl >/dev/null 2>&1; then
		TARGET_DETECT_FAILED=1
		return 0
	fi
	if command -v jq >/dev/null 2>&1; then
		api=$(curl -s --fail --max-time 30 https://get.opensuse.org/api/v0/distributions.json 2>/dev/null) && \
		target=$(jq -r --arg cur "$cur" '
			[.Leap[] | select(.state == "Stable") | .version
			 | select((tonumber) > ($cur | tonumber))]
			| sort_by(tonumber) | first // empty' <<<"$api" 2>/dev/null)
	fi
	# Fallback when jq is unavailable: probe the next major .0 release.
	if [ -z "$target" ]; then
		local cand="$((cur_major + 1)).0"
		curl -sfI --max-time 30 "https://download.opensuse.org/distribution/leap/${cand}/repo/oss/repodata/repomd.xml" >/dev/null 2>&1 && target="$cand"
	fi
	# Distinguish a real "nothing newer" from a network outage that silently
	# masked an available upgrade.
	if [ -z "$target" ] && ! curl -sfI --max-time 15 https://get.opensuse.org/ >/dev/null 2>&1; then
		TARGET_DETECT_FAILED=1
		return 0
	fi
	# Only migrate to a release grommunio actually builds for.
	if [ -n "$target" ]; then
		curl -sfI --max-time 30 "https://download.grommunio.com/community/openSUSE_Leap_${target}/repodata/repomd.xml" >/dev/null 2>&1 || target=""
	fi
	DETECTED_TARGET="$target"
}

# Distribution dup that stays on the current Leap version (latest packages only).
# Uses the same conflict-tolerant flags as the migration so an upgrade that was
# interrupted mid-dup can still converge on a re-run (those flags are no-ops
# when there is no conflict).
opensuse_in_version_dup() {
	zypper -n purge-kernels
	zypper -n --gpg-auto-import-keys ref && \
	zypper -n --gpg-auto-import-keys dup -y --replacefiles --auto-agree-with-licenses --force-resolution
}

# After re-pointing repositories to ${1}, disable any enabled repo whose target
# URL has no content. openSUSE Leap 16.0 dropped the dedicated update/sle/
# backports repositories, so without this a single unreachable repo would block
# the dist-upgrade. Repos that do have target content (oss, grommunio, ...) stay.
disable_unreachable_repos() {
	local target="$1" alias
	while read -r alias; do
		[ -z "$alias" ] && continue
		if ! zypper -n --releasever "$target" --gpg-auto-import-keys refresh "$alias" >/dev/null 2>&1; then
			echo -e "  ${YELLOW}disabling repository without ${target} content:${TXTRST} ${alias}"
			zypper -n modifyrepo -d "$alias" >/dev/null 2>&1
		fi
	done < <(zypper lr -E 2>/dev/null | awk -F'|' '$1 ~ /^[[:space:]]*[0-9]+[[:space:]]*$/ {gsub(/^[ \t]+|[ \t]+$/,"",$2); print $2}')
}

# "upgrade" on openSUSE Leap: migrate to the next distribution release if one is
# available (e.g. 15.6 -> 16.0), otherwise just dup within the current version.
# grommunio appliances use custom static repo aliases (base, update, grommunio,
# jeng, ...) and not the index-service openSUSE-repos package, so the release is
# switched manually like the community recipe: re-point the version in every
# repo, drop the ones the target no longer ships, then dup.
opensuse_leap_dist_upgrade() {
	local target free_kb postfix_was_active=0 repo_backup ver_re

	# Only Leap-family systems get a cross-version migration; Tumbleweed, SLES,
	# MicroOS etc. just dup within their current distribution.
	case "${ID}" in
		opensuse-leap|grommunio*) ;;
		*) opensuse_in_version_dup; return $? ;;
	esac

	echo -e "\n${BLUE}▶${TXTRST} Checking for a newer openSUSE Leap release..."
	detect_target_leap
	target="${DETECTED_TARGET}"

	if [ -z "${target}" ]; then
		if [ "${TARGET_DETECT_FAILED:-0}" -eq 1 ]; then
			echo -e "${YELLOW}▶${TXTRST} Could not determine the next Leap release (curl/jq or network unavailable); upgrading packages in place only."
		else
			echo -e "${GREEN}▶${TXTRST} Already on the latest supported openSUSE Leap (${VERSION_ID}); upgrading packages in place."
		fi
		opensuse_in_version_dup
		return $?
	fi

	echo -e "${YELLOW}▶${TXTRST} Migrating openSUSE Leap ${VERSION_ID} -> ${target}. This is a major upgrade and may take a while."

	if [ "$(uname -m)" = "x86_64" ] && [ "${target%%.*}" -ge 16 ] && ! cpu_supports_x86_64_v2; then
		echo -e "${RED}▶ Migration skipped.${TXTRST} openSUSE Leap ${target} requires an x86_64-v2 CPU; this host does not qualify and would fail to boot after the upgrade."
		echo -e "${YELLOW}▶${TXTRST} See https://en.opensuse.org/openSUSE:X86-64-Architecture-Levels - keeping ${VERSION_ID} and updating packages only."
		opensuse_in_version_dup
		return $?
	fi

	free_kb=$(df -Pk / | awk 'NR==2 {print $4}')
	if [ -n "${free_kb}" ] && [ "${free_kb}" -lt 8388608 ]; then
		echo -e "${RED}▶ Migration aborted.${TXTRST} Less than 8 GB free on / ($((free_kb / 1024)) MB available); free up space and retry."
		return 1
	fi

	# Keep NIC names stable so the new kernel/udev cannot rename them and leave
	# the box unreachable after the reboot.
	pin_interface_names

	# Free /boot before the upgrade.
	zypper -n purge-kernels

	# Switch the distribution manually. Back up repos.d first so a failed dup can
	# be rolled back instead of leaving a half-migrated host.
	repo_backup=$(mktemp -d)
	cp -a /etc/zypp/repos.d/. "${repo_backup}/"
	# Re-point hardcoded versions (base, grommunio, grommunio-obs, jeng, ...);
	# $releasever-based repos follow --releasever during refresh and dup.
	ver_re="${VERSION_ID//./\\.}"
	sed -i "s/${ver_re}/${target}/g" /etc/zypp/repos.d/*.repo
	# Disable repos the target no longer ships (16.0 dropped update/sle/backports).
	disable_unreachable_repos "${target}"

	# Stop postfix so mail is not lost or corrupted while binaries are replaced.
	if [[ "$(systemctl is-active postfix)" == "active" ]]; then
		postfix_was_active=1
		systemctl stop postfix
	fi

	# The distribution upgrade itself, with flags so it runs unattended:
	#   --replacefiles         python311 -> python313 style file conflicts
	#   --force-resolution     auto-pick a solution for branding/package conflicts
	#   --allow-vendor-change  allow grommunio <-> openSUSE vendor transitions
	echo -e "\n${BLUE}▶${TXTRST} Running zypper dup to openSUSE Leap ${target}..."
	if ! zypper -n --gpg-auto-import-keys --releasever "${target}" dup -y --replacefiles --auto-agree-with-licenses --force-resolution --allow-vendor-change --download in-advance; then
		echo -e "${YELLOW}▶${TXTRST} First dup pass reported problems, retrying once..."
		if ! zypper -n --gpg-auto-import-keys --releasever "${target}" dup -y --replacefiles --auto-agree-with-licenses --force-resolution --allow-vendor-change --download in-advance; then
			# Roll back the repository switch and bring mail back; stay on ${VERSION_ID}.
			rm -f /etc/zypp/repos.d/*.repo
			cp -a "${repo_backup}/." /etc/zypp/repos.d/
			rm -rf "${repo_backup}"
			[ "${postfix_was_active}" -eq 1 ] && systemctl start postfix
			return 1
		fi
	fi

	rm -rf "${repo_backup}"
	FORCE_REBOOT=1
	MIGRATED_TO="${target}"
	return 0
}

# Manual follow-up tasks after a major Leap migration that are too
# system-specific for grommunio-update to apply safely on its own.
print_post_migration_notes() {
	echo -e "\n${YELLOW}▶ openSUSE Leap ${MIGRATED_TO} migration finished - manual follow-up may be required:${TXTRST}"
	echo -e "  - A reboot is required to activate the new kernel (done automatically unless --noreboot was given)."
	echo -e "  - Postfix: replace deprecated smtp[d]_use_tls with smtp[d]_tls_security_level=may in /etc/postfix/main.cf, replace 'fifo' with 'unix' in /etc/postfix/master.cf, then run 'postfix check'."
	echo -e "  - Third-party repositories were disabled for the upgrade; re-enable and re-point them to ${MIGRATED_TO} if still needed ('zypper lr', 'zypper mr -e <repo>')."
	echo -e "  - SSH root password login: if needed, remove openssh-server-config-disallow-rootlogin or add PermitRootLogin yes under /etc/ssh/sshd_config.d/."
	echo -e "  - plymouth no longer works: 'systemctl mask plymouth-start.service plymouth-quit.service plymouth-quit-wait.service' and drop 'quiet splash' from /etc/default/grub."
	echo -e "  - Certbot is gone on 16.0: switch to acme.sh (or symlink certbot-3.13)."
	echo -e "  - Review leftover *.rpmnew / *.rpmsave files and re-apply your PHP-FPM pool changes under /etc/php8/fpm/php-fpm.d/."
	echo -e "  - Full step-by-step recipe: https://community.grommunio.com/d/2617"
}

# grommunio does not support AppArmor or SELinux in enforcing mode; make sure
# both are off (Leap 16.0 ships SELinux as the new default). Safe to re-run.
disable_apparmor_selinux() {
	if systemctl cat apparmor >/dev/null 2>&1; then
		if [[ "$(systemctl is-active apparmor)" == "active" ]] || [[ "$(systemctl is-enabled apparmor 2>/dev/null)" == "enabled" ]]; then
			echo -e "\n${BLUE}▶${TXTRST} Disabling AppArmor (unsupported by grommunio)"
			systemctl disable --now apparmor >/dev/null 2>&1
			systemctl mask apparmor >/dev/null 2>&1
		fi
	fi
	if command -v selinuxenabled >/dev/null 2>&1 && selinuxenabled; then
		setenforce 0 >/dev/null 2>&1
	fi
	if [ -f /etc/selinux/config ] && grep -qiE '^[[:space:]]*SELINUX[[:space:]]*=[[:space:]]*(enforcing|permissive)' /etc/selinux/config; then
		echo -e "\n${BLUE}▶${TXTRST} Disabling SELinux in /etc/selinux/config (unsupported by grommunio)"
		sed -i 's/^[[:space:]]*SELINUX[[:space:]]*=.*/SELINUX=disabled/I' /etc/selinux/config
	fi
}

# The grommunio-keycloak package now ships /opt/grommunio-keycloak/conf as a
# symlink to /etc/grommunio-keycloak. Where conf is still a real directory, copy
# its contents to /etc first so the config survives the package upgrade that
# replaces the directory with the symlink. Run before the package operation.
keycloak_preserve_conf() {
	rpm -q grommunio-keycloak >/dev/null 2>&1 || return 0
	if [ -d /opt/grommunio-keycloak/conf ] && [ ! -L /opt/grommunio-keycloak/conf ]; then
		echo -e "\n${BLUE}▶${TXTRST} Preserving grommunio-keycloak config to /etc/grommunio-keycloak"
		mkdir -p /etc/grommunio-keycloak
		# -n keeps any config already in /etc (it is the source of truth once
		# populated); surface failures so config loss is not silent.
		if ! cp -an /opt/grommunio-keycloak/conf/. /etc/grommunio-keycloak/; then
			echo -e "${RED}▶ Warning:${TXTRST} could not fully copy grommunio-keycloak config to /etc/grommunio-keycloak; verify it after the upgrade."
		fi
	fi
}

# Remove the rpm "conf;<hex>" artifacts left behind by the directory->symlink
# transition of grommunio-keycloak. Run after the package operation.
keycloak_cleanup_artifacts() {
	rpm -q grommunio-keycloak >/dev/null 2>&1 || return 0
	local f
	for f in '/opt/grommunio-keycloak/conf;'*; do
		{ [ -e "$f" ] || [ -L "$f" ]; } && rm -f "$f"
	done
}

# After a major distribution upgrade, grommunio-web's per-user sqlite search
# index uses a new format; drop it so it is rebuilt on next access.
reset_grommunio_web_index() {
	local idx=/var/lib/grommunio-web/sqlite-index
	if [ -d "$idx" ]; then
		echo -e "\n${BLUE}▶${TXTRST} Clearing grommunio-web search index for rebuild"
		find "$idx" -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null
	fi
}

# When triggered from a service (the admin web UI runs us inside the
# grommunio-admin-api cgroup via sudo), a dist-upgrade that restarts that
# service would otherwise kill this script mid-run. Re-exec into a transient
# systemd scope so we keep running independently until the work is done or the
# box reboots. CLI output and the logfile are unaffected (--scope keeps stdio).
# Only the long-running update/upgrade paths need this (not check/help), and we
# probe scope creation first so a systemd hiccup falls back to running inline.
case " $* " in
	*" update "*|*" upgrade "*)
		if [ -z "${GROMMUNIO_UPDATE_SCOPE:-}" ] && [ "$(id -u)" -eq 0 ] && [ -d /run/systemd/system ] \
			&& command -v systemd-run >/dev/null 2>&1 \
			&& systemd-run --scope --quiet --collect -- true >/dev/null 2>&1; then
			export GROMMUNIO_UPDATE_SCOPE=1
			exec systemd-run --scope --quiet --collect --unit="grommunio-update-$$" -- "$0" "$@"
		fi
		;;
esac

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="opensuse_leap_dist_upgrade"
		elif [[ ${OPERATION} == "update" ]]; then
			UPDATE_CMD="zypper -n purge-kernels && zypper -n --gpg-auto-import-keys ref && zypper -n up -y"
		else
			UPDATE_CMD="zypper ref && zypper lu"
		fi
		;;
	grommunio*)
		PKG_MANAGER="zypper"
		if [[ ${OPERATION} == "upgrade" ]]; then
			UPDATE_CMD="opensuse_leap_dist_upgrade"
		elif [[ ${OPERATION} == "update" ]]; then
			UPDATE_CMD="zypper -n purge-kernels && zypper -n --gpg-auto-import-keys ref && zypper -n 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
if [ "${PKG_MANAGER}" == "zypper" ] && [[ ${OPERATION} != "check" ]]; then
	keycloak_preserve_conf
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
		# grommunio uses an instanced redis service for caching (grommunio still
		# requires redis on Leap 16.0, not valkey); make sure it is enabled and up.
		if systemctl cat redis@grommunio >/dev/null 2>&1; then
			systemctl enable redis@grommunio >/dev/null 2>&1
			if [[ "$(systemctl is-active redis@grommunio)" != "active" ]]; then
				systemctl restart redis@grommunio
			fi
		fi
		if [[ ! -e /etc/php8/fpm/php-fpm.conf ]] && [[ -e /etc/php8/fpm/php-fpm.conf.default ]]; then
			mv /etc/php8/fpm/php-fpm.conf.default /etc/php8/fpm/php-fpm.conf
			systemctl enable php-fpm
			systemctl restart php-fpm
		fi
		# A distribution upgrade renames /etc/pam.d/smtp to .rpmsave, which
		# breaks Postfix SASL (pam_gromox); restore it if it was displaced.
		if [[ -f /etc/pam.d/smtp.rpmsave ]] && [[ ! -f /etc/pam.d/smtp ]]; then
			mv /etc/pam.d/smtp.rpmsave /etc/pam.d/smtp
		fi
		keycloak_cleanup_artifacts
		disable_apparmor_selinux
		# A major distribution upgrade brings a new grommunio-web index format.
		if [[ -n "${MIGRATED_TO:-}" ]]; then
			reset_grommunio_web_index
		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

if [[ -n "${MIGRATED_TO:-}" ]]; then
	print_post_migration_notes
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 ] || [[ ${FORCE_REBOOT:-0} -eq 1 ]]; 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
