#!/bin/bash
# Run garuda hooks related commands.

source /usr/lib/garuda/garuda.shlib

if [ ! -e /usr/share/garuda/migrations/current_version ]; then
	exit 1
fi

IS_NEW_INSTALL=false
pending_version=$(</usr/share/garuda/migrations/current_version)

if [ -e /etc/garuda/migrations/applied_version ]; then
	applied_version=$(</etc/garuda/migrations/applied_version)
else
	IS_NEW_INSTALL=true
	applied_version=0.0.0
fi

grub_has_ibt_fix() {
	grep -qe "^GRUB_CMDLINE_LINUX_DEFAULT=.*ibt=off" /etc/default/grub
}

grub_has_splash() {
	grep -qe "^GRUB_CMDLINE_LINUX_DEFAULT=.*splash" /etc/default/grub
}

# $1 Previous version
# $2 Current version
apply_migrations() {
	echo "$2" >/etc/garuda/migrations/applied_version

	# Uninstall sddm DPI fix
	if [[ $(vercmp 1.1.0-1 $1) -gt 0 ]]; then
		rm -f /etc/sddm.conf.d/01-garuda-fix-dpi.conf
	fi

	# Update updatedb.conf with some sane snapper defaults
	if [[ $(vercmp 1.2.0-1 $1) -gt 0 ]]; then
		sed -e 's_^PRUNEPATHS = "/afs /media /mnt /net /sfs /tmp /udev /var/cache /var/lib/pacman/local /var/lock /var/run /var/spool /var/tmp"_# Modified by Garuda Linux to exclude snapshots\nPRUNEPATHS = "/afs /media /mnt /net /sfs /tmp /udev /var/cache /var/lib/pacman/local /var/lock /var/run /var/spool /var/tmp /.snapshots"_' -i /etc/updatedb.conf
	fi

	# Update /etc/mkinitcpio.conf to include grub-btrfs-overlayfs
	if [[ $(vercmp 1.3.0-1 $1) -gt 0 ]] && [ "$IS_NEW_INSTALL" == "false" ] && [ -f /etc/mkinitcpio.conf ] && ! grep -qe "^HOOKS=.*grub-btrfs-overlayfs" /etc/mkinitcpio.conf; then
		sed -re 's/(^HOOKS=\([^)]+)/\1 grub-btrfs-overlayfs/gi' -i /etc/mkinitcpio.conf
	fi

	if [[ $(vercmp 1.4.0-1 $1) -gt 0 ]]; then
		gawk -i inplace -v new_install="$IS_NEW_INSTALL" '/^deny/ {
            set=1
          }
          ENDFILE {
            if (!set) {
              if (new_install != "true") {
                print "deny = 10 # Modified by Garuda Linux"
              } else {
                print "deny = 10"
              }
            }
          }
          1' /etc/security/faillock.conf
		garudalib_add_update_notice "The default faillock limit was automatically changed to 10 (from 3)"
	fi

	# Enable grub recovery
	if [[ $(vercmp 2.1.0-1 $1) -gt 0 ]]; then
		gawk -i inplace -v new_install="$IS_NEW_INSTALL" -F "=" '/^GRUB_DISABLE_RECOVERY=.*$/ {
            if ($2 == "true") {
              set=1
              if (new_install != "true") {
                print "# Modified by garuda-migrations: GRUB_DISABLE_RECOVERY=default"
              }
              print "#"$0
              next
            } else {
              print
            }
          }
          ENDFILE {
            if (!set) {
              exit 1
            }
          }
          1' /etc/default/grub &&
			garudalib_add_update_notice "A recovery mode option was added to your advanced options in the GRUB bootloader." || true
	fi

	# Remove legacy intel IBT kernel parameter which was used to fix an NVIDIA kernel module issue
	if [[ $(vercmp 2.2.0-1 $1) -gt 0 ]] && [ "$IS_NEW_INSTALL" == "false" ] && grub_has_ibt_fix; then
		sed -i '/# Modified by garuda-migrations: ibt=off/ s/# Modified by garuda-migrations: ibt=off//; s/\s*ibt=off//g' /etc/default/grub
	fi

	# Handle plymouth migration
	if [[ $(vercmp 2.3.1-1 $1) -gt 0 ]] && [ "$IS_NEW_INSTALL" == "false" ]; then
		if [ -f /etc/mkinitcpio.conf ] && grep -qe '^HOOKS=.*\(plymouth-encrypt\|sd-plymouth\)' /etc/mkinitcpio.conf; then
			sed -E '/^HOOKS=\(.*\)$/ s/(plymouth-encrypt)/encrypt/g; /^HOOKS=\(.*\)$/ s/(sd-plymouth)/plymouth/g' -i /etc/mkinitcpio.conf
			garudalib_add_update_notice "The mkinitcpio configuration for plymouth was updated to a new format automatically." || true
		fi
		dm_service="$(basename "$(readlink -sf /etc/systemd/system/display-manager.service || true)")"
		case "$dm_service" in
		"lxdm-plymouth.service") ;&
		"sddm-plymouth.service") ;&
		"lightdm-plymouth.service")
			new_dm_service="${dm_service%-plymouth.service}.service"
			systemctl disable "$dm_service"
			systemctl enable "$new_dm_service"
			garudalib_add_update_notice "Your default display manager was changed from \"$dm_service\" to \"$new_dm_service\" automatically, because the former no longer exists." || true
			;;
		esac
	fi

	# Remove plymouth from grub
	if [[ $(vercmp 2.4.1-1 $1) -gt 0 ]] && grub_has_splash; then
		gawk -i inplace '
      /^GRUB_CMDLINE_LINUX_DEFAULT=.*/ {
        if (gsub(/ ?splash/, "") > 0) {
            print $0" # Modified by garuda-migrations: splash"
            set=1
            next
        }
      }
      ENDFILE {
        if (!set) {
          exit 1
        }
      }
      1' "/etc/default/grub" && garudalib_add_update_notice 'The "splash" (Plymouth) kernel parameter was removed from your GRUB configuration automatically to ensure system stability. Plymouth may be enabled manually again, but it is strongly recommended to keep plymouth disabled.' || true
	fi

	# Add info about plocate migration
	if [[ $(vercmp 2.5.2-1 $1) -gt 0 ]] && [ "$IS_NEW_INSTALL" == "false" ]; then
		garudalib_add_update_notice "Arch dropped mlocate in favor of plocate. Service migrations have already been applied by garuda-update, but you definitely also want to migrate your .pacsave files by running this command: 'sudo mv /etc/updatedb.conf.pacsave /etc/updatedb.conf'. More information can be found here: https://forum.garudalinux.org/t/39190/2." || true
	fi

	# Remove /etc/polkit-1/rules.d/49-nopasswd-live.rules if not on live system
	if [[ $(vercmp 2.6.0-1 $1) -gt 0 ]] && [ "$IS_NEW_INSTALL" == "false" ]; then
		if [ ! -d "/run/miso" ] && [ -f "/etc/polkit-1/rules.d/49-nopasswd-live.rules" ]; then
			rm -f /etc/polkit-1/rules.d/49-nopasswd-live.rules
			# No need to be chatty for no reason for a relatively minor fix
		fi
	fi

	# Disable psd.service on the user accounts
	if [[ $(vercmp 3.0.1-1 $1) -gt 0 ]] && [ "$IS_NEW_INSTALL" == "false" ]; then
		if systemctl is-enabled --global --quiet psd.service; then
			systemctl disable --global psd.service
			garudalib_add_update_notice "Profile Sync Daemon (psd) was disabled automatically. The Garuda Linux developers do not recommend using psd. To continue using psd, mark the pacman package as explicitly installed and enable the service manually: 'sudo pacman -D --asexplicit profile-sync-daemon && systemctl --global enable psd.service'."
		fi
	fi

	# Disable udevadm trigger on update via /etc/systemd/do-not-udevadm-trigger-on-update
	if [[ $(vercmp 3.1.0-1 $1) -gt 0 ]]; then
		local flag_file="/etc/systemd/do-not-udevadm-trigger-on-update"
		if [ ! -e "${flag_file}" ]; then
			if [ "$IS_NEW_INSTALL" == "false" ]; then
				# Leave a flag behind so this can be reverted if needed
				echo "# Modified by garuda-migrations" >"${flag_file}"
			else
				touch "${flag_file}"
			fi
			garudalib_add_update_notice "The file "${flag_file}" was created automatically to prevent crashes on certain hardware during system updates. The file can safely be deleted if running a udevadm trigger after updates to systemd/udev files is desired."
		fi
	fi

	# Re-enable wayland support for GDM
	if [[ $(vercmp 3.2.0-1 $1) -gt 0 ]]; then
		local gdm_conf_file="/etc/gdm/custom.conf"
		if [ -f "${gdm_conf_file}" ]; then
			if grep -q '^WaylandEnable=false[[:space:]]*' "${gdm_conf_file}"; then
				sed -i 's_^WaylandEnable=false[[:space:]]*_# Modified by garuda-migrations: WaylandEnable=false\n#WaylandEnable=false_' "${gdm_conf_file}"
				garudalib_add_update_notice "Wayland support for GDM was re-enabled automatically by changing the setting "WaylandEnable" to default in \"${gdm_conf_file}\"."
			fi
		fi
	fi

	# Add "systemd" to nsswitch.conf if not present
	if [[ $(vercmp 3.3.0-1 $1) -gt 0 ]] && ( [ "$IS_NEW_INSTALL" == "false" ] || [ ! -f /usr/lib/garuda/garuda-release ] ); then
		gawk -i inplace '
	  BEGIN {
		set=0
	  }
	  # Match any of "passwd", "group", "shadow", "gshadow" at the start of the line
	  /^(passwd|group|shadow|gshadow):/ {
		# Check if "systemd" is present
		if ($0 !~ /systemd( |$)/) {
			# Add systemd at the end of the line
			$0 = $0" systemd"
			set=1
		}
	  }
	  ENDFILE {
		if (!set) {
		  exit 1
		}
	  }
	  1' /etc/nsswitch.conf && garudalib_add_update_notice 'The "systemd" module was added to /etc/nsswitch.conf automatically to improve compatibility with GNOME.' || true
	fi

	# Remove old garuda grub.d drop in support from /etc/default/grub
	if [[ $(vercmp 3.4.1-1 $1) -gt 0 ]] && [ "$IS_NEW_INSTALL" == "false" ] && [ -f /etc/default/grub ]; then
		local filename="/etc/default/grub"
		if grep -q '${garuda_grub_d}' $filename; then
			sed -rzi 's|# This config file imports drop-in files from /etc/default/grub\.d/\.\nfor garuda_grub_d in \$\{sysconfdir\}/default/grub\.d/\*\.cfg ; do if \[ -e "\$\{garuda_grub_d\}" \]; then source "\$\{garuda_grub_d\}"; fi; done\n?||g' /etc/default/grub
			garudalib_add_update_notice '/etc/default/grub was automatically edited to remove unnecessary logic related to drop in files from /etc/default/grub.d/. This is handled in the "grub" package instead.' || true
		fi
	fi

	# If Sweet6 and sddm are installed, switch to the Sweet6 sddm theme
	if [[ $(vercmp 3.4.3-1 $1) -gt 0 ]] && [ "$IS_NEW_INSTALL" == "false" ] && [ -f /etc/sddm.conf ] && [ -f /usr/share/sddm/themes/Sweet6/theme.conf ]; then
		if grep -q '^Current=Sweet$' /etc/sddm.conf; then
			sed -i 's/^Current=Sweet$/Current=Sweet6 # Modified by garuda-migrations: Sweet -> Sweet6/' /etc/sddm.conf
			garudalib_add_update_notice 'The SDDM theme was automatically changed from "Sweet" to "Sweet6" because plasma-framework5 was removed from the repositories.' || true
		fi
	fi
}

# $1 Previous version
# $2 Current version
apply_user_migrations() {
	if [[ $(vercmp 3.0.0-1 $1) -gt 0 ]] && [ "$IS_NEW_INSTALL" == "false" ] && [ -f ".config/fish/config.fish" ]; then
		# Replace --load-config neofetch with --config neofetch.jsonc
		# and --load-config dr460nized with --config dr460nized.jsonc
		sed -i -e 's/fastfetch --load-config neofetch/fastfetch --config neofetch.jsonc/g' \
			-e 's/fastfetch --load-config dr460nized/fastfetch --config dr460nized.jsonc/g' \
			".config/fish/config.fish" 2>/dev/null || true
	fi
}

apply_migrations "$applied_version" "$pending_version"

# Apply user migrations
# shellcheck disable=2034
while IFS=: read -r name password uid gid gecos home shell; do
	# Skip system users
	if [ "$uid" -lt 1000 ] || [ "$uid" -eq 65534 ]; then
		continue
	fi
	# Skip users without home directory
	if [ -z "$home" ] || [ ! -d "$home" ] || [ "$home" == "/" ]; then
		continue
	fi
	# Skip users with no shell
	if [ -z "$shell" ] || [ ! -x "$shell" ] || [ "$shell" == "/usr/bin/nologin" ] || [ "$shell" == "/bin/false" ]; then
		continue
	fi

	pushd "$home" >/dev/null || continue
	USER_UID="$uid" USER_NAME="$name" apply_user_migrations "$applied_version" "$pending_version"
	popd >/dev/null || continue
done < <(getent passwd)