#!/bin/bash
#=========================================#
# Simple update notifier CLI (DNF) v0.3.8 #
#=========================================#

# Run as root
USER=$(who | awk '{print $1}' | head -n1)
CONF="/home/$USER/.config/simple-notifier"
name="history"
date=$(date)
LOG="$name.cli"

# Check if dnf is running
RUN=$(ps -ef | grep "dnf" | grep -v grep | wc -l)
if [[ "$RUN" -gt 0 ]]; then
/usr/share/simple-notifier/warning.py
exit 0
fi
# Ensure config folder exists
if [[ ! -d "$CONF" ]]; then
    mkdir -p "$CONF"
    chown -R "$USER:$USER" "$CONF"
fi

# Create/update log file
touch "$CONF/$name.cli"

######## Define colors #########
bblu=$(tput setab 4)
bwht=$(tput setab 7)
blk=$(tput setaf 0)
blue=$(tput setaf 4)
yll=$(tput setaf 3)
wht=$(tput setaf 7)
bld=$(tput bold)
dim=$(tput dim)
reset=$(tput sgr0)

nshw() { tput civis; }
yshw() { tput cnorm; }

SimpleUpdater_Color=${bblu}${bld}${wht}
SimpleUpdater_msg=${bld}${bblu}${wht}
SimpleUpdater_good=${bld}${wht}
SimpleUpdater_note=${bld}${wht}
SimpleUpdater_err=${bld}${bblu}${yll}

title() { printf "${SimpleUpdater_Color} %s${reset}\n" "$@"; }
msg() { printf "${SimpleUpdater_msg}  ${reset}${bld}%s \n${reset}" "$@"; }
complete() { 
    [[ "$@" == "" ]] && printf " ${SimpleUpdater_good}[ ✔ COMPLETED ] ${reset}\n" || printf " ${SimpleUpdater_good}[ ✔ %s ] ${reset}\n" "$@"
}
notes() { printf "${SimpleUpdater_note} > ${reset} %s \n" "$@"; }
warning() { [[ "$@" == "" ]] && printf "${SimpleUpdater_err} [ ⚠ WARNING ] ${reset}\n"; printf "${SimpleUpdater_err} [ ⚡ %s ] ${reset}\n" "$@"; }

root_check() { [[ $(id -u) -ne 0 ]] && ls >/dev/null; }

################ Updating functions #################
UPDATE() { 
    dnf check-update -q | awk '/^[a-zA-Z0-9]/' >> "$CONF/$name.cli"
}
UPGRADE() { 
    dnf -y upgrade >> "$CONF/$name.cli"
}
CLEANUP() { 
    dnf clean all >> "$CONF/$name.cli"
}
FINAL() { echo; }

################ Progress spinner ###################
rotate() { 
    nshw
    SPINNER="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
    spinner() {
        task=$1
        msg=$2
        while :; do
            jobs %1 > /dev/null 2>&1
            [[ $? -eq 0 ]] || { complete "$task Done"; break; }
            for ((i=0;i<${#SPINNER};i++)); do
                sleep 0.05
                printf "${bld}${blue}${SPINNER:$i:1}${reset} ${SimpleUpdater_msg} ${task} ${msg}${reset}\r"
            done
        done
    }
    msg="${2-InProgress}"
    task="${3-$1}"
    $1 & spinner "$task" "$msg"
    yshw
}

################ System Update ###################
sysupdate() {
    title "▞ ▞ ▞ ▞ ▞ ▞ ▞ ▞ Simple-Updater CLI ▚ ▚ ▚ ▚ ▚ ▚ ▚ ▚ "
    echo "__________________________________________________________" >> "$CONF/$name.cli"
    echo $date >> "$CONF/$name.cli"

    msg "Creating list of available updates..."  
    echo "Creating list of available updates" >> "$CONF/$name.cli"
    warning "... This may take some time ..." 
    rotate 'UPDATE' "Updated list..." "Downloading"

    msg "Installing system updates..."  
    echo "Installing system updates..." >> "$CONF/$name.cli"
    warning "... Please be patient ..."
    rotate "UPGRADE" "Updates..." "Installing"

    msg "Cleaning system..."  
    echo "Removing stale packages..." >> "$CONF/$name.cli"
    rotate "CLEANUP" "Removing unnecessary packages..." "Cleaning"

    msg "Finalizing..."
    echo "Done" >> "$CONF/$name.cli"
    rotate "FINAL" "" "Finalizing"

    chown -R "$USER:$USER" "$CONF/$name.cli"

}

message_final() {
    title " ▞ ▞ ▞ ▞ System Updates Applied ▚ ▚ ▚ ▚  "
    echo
    read -n1 -p " Press ${bld}\"Q\"${reset} to quit, or ${bld}\"L\"${reset} to view the log file." pause 
# Reset
sleep 5;
# File paths
UPDATE_COUNT_FILE="/var/tmp/.simple-notifier/num_updates"
UPDATE_LIST_FILE="/var/tmp/.simple-notifier/show_info"
TMP_COUNT_FILE="/var/tmp/.simple-notifier/tmp_num_updates"
TMP_LIST_FILE="/var/tmp/.simple-notifier/tmp_show_info"

# Function to check updates
run_check() {
    dnf -q check-update --refresh 2>/dev/null | awk -v tmp_count="$TMP_COUNT_FILE" -v tmp_list="$TMP_LIST_FILE" '
    BEGIN {
        c=0
        in_obsolete=0
        written=0
        delete found_packages
    }

    /^Obsoleting/ {in_obsolete=1; next}

    !in_obsolete && NF > 1 && /^[[:alnum:]]/ {
        if (!($1 in found_packages)) {
            found_packages[$1]
            if (!written) {
                print > tmp_list
                written=1
            } else {
                print >> tmp_list
            }
            c++
        }
        next
    }

    in_obsolete && NF > 2 && /^[[:alnum:]]/ {
        if ($3 != "<unknown>" && !($1 in found_packages)) {
            found_packages[$1]
            if (!written) {
                print > tmp_list
                written=1
            } else {
                print >> tmp_list
            }
            c++
        }
    }

    END {
        print c > tmp_count
    }'

    # Move temporary files to their final destination
    mv -f "$TMP_COUNT_FILE" "$UPDATE_COUNT_FILE"
    mv -f "$TMP_LIST_FILE" "$UPDATE_LIST_FILE"
    chmod 0777 "$UPDATE_COUNT_FILE" "$UPDATE_LIST_FILE"
    # Remove junk files
    rm -f $CONFIG/tmp_*  
 }

run_check

}                                                                      

view_log() {                                                          
    [ "$pause" = "l" ] || [ "$pause" = "L" ] && (
        clear
        echo "0" > /var/tmp/.simple-notifier/num_updates
        ICON='/usr/share/icons/hicolor/48x48/apps/simple-notifier.png'
        yad --width=675 --height=400 --center \
            --text-info --filename="$CONF/$name.cli" \
            --window-icon=$ICON \
            --image=$ICON \
            --title='Simple Updater CLI History' \
            --button="Delete"!gtk-delete:1 \
            --button="Close"!gtk-quit:0
        ret=$?
        if [ $ret -eq 1 ]; then
            exit 0
        elif [ $ret -eq 3 ]; then
            rm -f "$CONF/$name.cli" >/dev/null 2>&1
        fi
        clear
    ) || clear
}

#================ Main =================#
clear
root_check
sysupdate
message_final
view_log

