#!/bin/bash
set -euo pipefail

# Define the log file path
log_file="/var/log/trup.log"
: >"$log_file"

exec 3>&1                 # save current stdout (fd 3 → terminal)
exec 1>>"$log_file"       # stdout  → log
exec 2>&1                 # stderr  → same log

# Function to monitor and estimate the progress
monitor_progress() {
    local total_pkgs=0
    local retr=0
    local inst=0
    local last_percent=-1

    # captures “(cur/total)”
    local re_plan='([0-9]+)/([0-9]+)'
    # only match Retrieving lines
    local re_retr="^Retrieving:[[:space:]].*\\($re_plan\\)"
    # match “ Installing:” or “ Removing:” lines
    local re_inst="^[[:space:]]*\\($re_plan\\)[[:space:]]+(Installing|Removing):"

    # wait until you see the “Options:” line
    local started=0

    while IFS= read -r line; do

        if (( started == 0 )) && [[ "$line" =~ Options:\ .* ]]; then
            started=1
            continue
        fi
        (( started == 0 )) && continue

        # once you see any "(cur/total)", grab total
        if [[ $line =~ $re_plan ]]; then
            total_pkgs=${BASH_REMATCH[2]}
        fi

        # update retr to the matched “current” on a Retrieving line
        if [[ $line =~ $re_retr ]]; then
            retr=${BASH_REMATCH[1]}
        fi

        # update inst to the matched “current” on an Installing/Removing line
        if [[ $line =~ $re_inst ]]; then
            inst=${BASH_REMATCH[1]}
        fi

        if (( total_pkgs > 0 )); then
            # finished = retr+inst (each package counted twice)
            local finished=$(( retr + inst ))
            local percent=$(( finished * 100 / (2 * total_pkgs) ))

            if (( percent != last_percent )); then
                echo "${percent}%" >&3
                last_percent=$percent
            fi

            # stop once we've seen both phases for every package
            if (( finished >= 2 * total_pkgs )); then
                break
            fi
        fi
    done < <(tail -s 2 -n 0 -F "$log_file")
}


run_update() {
    echo "0%" >&3
    # Run the transactional-update command and redirect output to the log file
    transactional-update -c dup &
    pid=$!
    
    # Start the monitor_progress function in the background
    monitor_progress &
    mon_pid=$!

    # Wait for the transactional-update command to finish; don't let a non‑zero exit kill the script
    if ! wait $pid; then
        tu_status=$?
    else
        tu_status=0
    fi

    kill $mon_pid || true
    # workaround to kill the tail process that is started in a subshell
    pkill -u root -f "tail -s 2 -n 0 -F $log_file" || true
    echo "100%" >&3

    return $tu_status
}

check_update() {
    transactional-update -c run zypper --gpg-auto-import-keys --non-interactive refresh || true
    # Run zypper lu and count the number of update entries
    update_count=$(zypper lu | tail -n +5 | grep -c ' | ' || true)

    # Check the update count
    if [ "$update_count" -eq 0 ]; then
        echo "No updates available."
        return 7
    else
        echo "Updates are available."
        return 0
    fi
}

check_branch() {
    BRANCH_PATH="/etc/trup/source.conf"
    . "$BRANCH_PATH"

    # Check if OLD_REPO and OLD_BRANCH are set
    if [ -n "$OLD_REPO" ] && [ -n "$OLD_BRANCH" ]; then
        # Compare with current REPO and BRANCH
        if [ "$OLD_REPO" != "$REPO" ] || [ "$OLD_BRANCH" != "$BRANCH" ]; then
            # Remove old repository
            echo "Removing repository ${OLD_REPO//:/_}_${OLD_BRANCH} saved as ${NAME}_${OLD_BRANCH}..."
            zypper rr ${NAME}_${OLD_BRANCH}

            # Add new repository
            echo "Adding repository ${REPO//:/_}_${BRANCH} as ${NAME}_${BRANCH}..."
            if zypper lr | grep -q "openSUSE-Slowroll-Oss"; then
                echo "Slowroll repository found. Adding Slowroll repository."
                zypper --gpg-auto-import-keys --non-interactive ar -p 90 -f "https://download.opensuse.org/repositories/${REPO//:/:/}:/${BRANCH}/openSUSE_Slowroll/" ${NAME}_${BRANCH}
            else
                echo "Slowroll repository not found. Adding Tumbleweed repository."
                zypper --gpg-auto-import-keys --non-interactive ar -p 90 -f "https://download.opensuse.org/repositories/${REPO//:/:/}:/${BRANCH}/openSUSE_Tumbleweed/" ${NAME}_${BRANCH}
            fi
        fi
    fi
    sed -i "s/^OLD_REPO=.*/OLD_REPO=${REPO}/" /etc/trup/source.conf
    sed -i "s/^OLD_BRANCH=.*/OLD_BRANCH=${BRANCH}/" /etc/trup/source.conf
}


main() {
    if [ $EUID -ne 0 ]; then
        echo "$(basename $0) must be run as root"
        exit 1
    fi

    TRUP_CHECK_UPDATE=0
    TRUP_STEAM_PROGRESS=0

    while (( "$#" )); do
        case $1 in
            --check)
                TRUP_CHECK_UPDATE=1
                shift
                ;;
            -*|--*)
                echo "Unknown argument $1"
                exit 1
                ;;
        esac
    done
    
    check_branch
    
    if [ $TRUP_CHECK_UPDATE -eq 1 ]; then
   	check_update
   	exit_status=$?  # Capture the exit status of check_update
        exit $exit_status
    fi
    
    run_update
    ret=$?

    # If run_update failed with something other than “10” (nothing to do),
    # propagate that failure back to Steam:
    if [[ $ret -ne 0 && $ret -ne 10 ]]; then
        exit $ret
    fi
}

if [ "$0" = "$BASH_SOURCE" ] ; then
    main "$@"
fi
