#!/bin/sh
# Muted Tune: upgrade the Muted Tune packages, and nothing else. Installed as /usr/lib/mutedtune/update-helper by the
# desktop package. The window runs it through polkit (`pkexec`, which asks for the person's password in the system's own
# dialog; policy: /usr/share/polkit-1/actions/com.mutedtune.update.policy).
#
# It takes NO arguments and reads no environment of the caller: what to upgrade and how are fixed below, so a caller
# cannot steer a root process. Extra arguments are ignored.
#
# Exit status (the window turns these into plain words):
#   0   upgraded, or already current
#   10  the software source could not be reached or refreshed
#   11  another program is using the package manager right now
#   12  the package manager refused or failed the upgrade
#   13  Muted Tune is not installed through this system's package manager
set -u
PATH=/usr/sbin:/usr/bin:/sbin:/bin
export PATH
umask 022
LC_ALL=C
export LC_ALL
unset IFS BASH_ENV ENV APT_CONFIG DPKG_ROOT LD_PRELOAD LD_LIBRARY_PATH http_proxy https_proxy

OWN="mutedtune-desktop mutedtune mutedtune-runner"
SRC=/etc/apt/sources.list.d/mutedtune.sources
LOG=$(mktemp /run/mutedtune-update.XXXXXX 2>/dev/null) || LOG=/dev/null
trap '[ "$LOG" = /dev/null ] || rm -f "$LOG"' EXIT

# print the last few lines of what the package manager said (stderr: the window shows the last one as the reason)
tail_log() { [ "$LOG" = /dev/null ] || tail -n 6 "$LOG" >&2; }
busy() { grep -qiE 'could not get lock|unable to acquire|is another process using it|waiting for process|already locked|another app is currently holding' "$LOG" 2>/dev/null; }

if command -v dpkg-query >/dev/null 2>&1 && command -v apt-get >/dev/null 2>&1; then
    DEBIAN_FRONTEND=noninteractive
    APT_LISTCHANGES_FRONTEND=none
    NEEDRESTART_MODE=a
    export DEBIAN_FRONTEND APT_LISTCHANGES_FRONTEND NEEDRESTART_MODE
    have=
    for p in $OWN; do
        [ "$(dpkg-query -W -f='${db:Status-Status}' "$p" 2>/dev/null)" = installed ] && have="$have $p"
    done
    [ -n "$have" ] || { echo "Muted Tune is not installed through apt." >&2; exit 13; }
    # Refresh only our own source when it is where our package put it (the rest of the system's lists are left alone);
    # a source added by hand elsewhere gets the ordinary full refresh.
    if [ -f "$SRC" ]; then
        apt-get update -o Dir::Etc::sourcelist=sources.list.d/mutedtune.sources -o Dir::Etc::sourceparts=- -o APT::Get::List-Cleanup=0 >"$LOG" 2>&1
    else
        apt-get update >"$LOG" 2>&1
    fi
    rc=$?
    if [ $rc -ne 0 ]; then
        busy && { tail_log; exit 11; }
        tail_log; exit 10
    fi
    # shellcheck disable=SC2086  # $have is a fixed list of package names
    apt-get install --only-upgrade -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef $have >"$LOG" 2>&1
    rc=$?
    if [ $rc -ne 0 ]; then
        busy && { tail_log; exit 11; }
        tail_log; exit 12
    fi
    exit 0
elif command -v rpm >/dev/null 2>&1 && command -v dnf >/dev/null 2>&1; then
    have=
    for p in $OWN; do rpm -q "$p" >/dev/null 2>&1 && have="$have $p"; done
    [ -n "$have" ] || { echo "Muted Tune is not installed through dnf." >&2; exit 13; }
    # shellcheck disable=SC2086
    dnf -y --refresh upgrade $have >"$LOG" 2>&1
    rc=$?
    if [ $rc -ne 0 ]; then
        busy && { tail_log; exit 11; }
        grep -qiE 'cannot download|failed to download|could not resolve|failed to synchronize|curl error|status code' "$LOG" && { tail_log; exit 10; }
        tail_log; exit 12
    fi
    exit 0
fi
echo "This computer's package manager is not supported." >&2
exit 13
