#!/bin/bash

# omarchy:summary=Update system packages in rollback-safe groups with omadora-sync
# omarchy:requires-sudo=true

set -e

# omadora-sync upgrades in groups (kernel, graphics stack, system core,
# desktop, the rest), rebuilds kernel modules and Limine boot images after a
# kernel or driver change, and rolls a failed group back. It leaves user
# Flatpaks to omarchy-update-aur-pkgs. sudo resolves commands against its own
# secure_path, which never contains a checkout, so pass the full path.
#
# Migrations run after this step, so the first update of an install that
# predates omadora-sync has no libdnf5 bindings yet; that one upgrade runs as
# plain dnf and the migration installs them for every update after it.
if omarchy-pkg-present python3-libdnf5; then
  updater=("$OMARCHY_PATH/bin/omadora-sync" cli)
else
  updater=(dnf upgrade -y)
fi

# The conflict handler's last resort: the updater puts its questions to the
# person running the update instead of answering them itself. Nothing here may
# capture a stream, because an upgrade without -y prompts on stderr. The
# handler has already said why, so no heading here either.
if [[ ${OMARCHY_UPDATE_CONFLICT:-} == 1 && ${OMARCHY_UPDATE_INTERACTIVE:-} == 1 ]]; then
  # Raw dnf: by the time a human is asked, omadora-sync has already rolled its
  # own transaction back, so this is just the manual retry. dnf only resolves a
  # conflict by erasing a package, and only asks when allowed to: no -y, so the
  # person sees what would be removed and confirms or declines it.
  exec omarchy-update-dnf dnf upgrade --allowerasing
fi

echo -e "\e[32m\nUpdate system packages\e[0m"

errors=$(mktemp)
trap 'rm -f "$errors"' EXIT

# /usr/share/omarchy is wholly Omarchy's; files can land there unowned and would
# otherwise abort the upgrade. RPM refuses to overwrite files it doesn't own,
# so those are cleared by the conflict handler below.
#
# Progress bars stay on stdout. Errors are on stderr, kept for the conflict
# handler below; LC_ALL=C is what keeps them parseable in any locale.
if LC_ALL=C omarchy-update-dnf "${updater[@]}" 2>"$errors"; then
  cat "$errors" >&2
  exit 0
fi
cat "$errors" >&2

# The handler takes it from here: it clears files dnf doesn't own yet and
# runs this again, and puts a package conflict to whoever started the update.
# Anything else, including a second failure, is for a human.
[[ ${OMARCHY_UPDATE_RETRY:-} != 1 ]] || exit 1
# exec, so the EXIT trap above does not fire and the handler can still read the
# report. It takes over deleting it.
exec env OMARCHY_UPDATE_CONFLICT=1 omarchy-update-system-pkgs-when-conflicted "$errors"
