#!/bin/bash

# Script to upgrade SolydXK 9 to SolydXK 10
# Arjen Balfoort, 31-07-2019

# Check if this script is run as root
if [ $UID -ne 0 ]; then
  echo 'Please, type root password...'
  su -c "$0 $@"
  exit
fi

# Ask user for an unattended upgrade
APT='apt-get'
echo
read -p "Do you feel brave enough to run an unattended upgrade (y/N)?" ANSWER
case "$ANSWER" in 
    y|Y )
        # Make this script unattended
        # https://debian-handbook.info/browse/stable/sect.automatic-upgrades.html
        export DEBIAN_FRONTEND=noninteractive
        APT="yes '' | apt-get -y -o DPkg::options::=--force-confdef -o DPkg::options::=--force-confold"
        ;;
esac

# Save log file
UNM=$(logname)
LOG="/home/$UNM/solydxk10-upgrade.log"

# Get version
XK='solydx'; [ -e '/usr/bin/kdeinit5' ] && XK='solydk'
echo -e "\n>>> Start $XK upgrade to SolydXK 10 (Debian Buster)\n" | tee "$LOG"
echo "    Log: $LOG" | tee -a "$LOG"

# Packages that deborphan must NOT treat as orphans - comma separated list
# Set to '*' to keep everything
NOTORPHAN='baloo,virtualbox-guest-x11,virtualbox-guest-dkms,virtualbox-guest-utils'

# Fix apt
echo -e '\n>>> Fix apt in case of broken installs\n' | tee -a "$LOG"
dpkg --configure -a
apt-get install -f

# Pre-seeds for debconf
echo -e '\n>>> Pre-seed debconf (fix db first)\n' | tee -a "$LOG"
FIXDB='/usr/share/debconf/fix_db.pl'; [ -f "$FIXDB" ] && perl "$FIXDB" | tee -a "$LOG"
echo 'keyboard-configuration keyboard-configuration/model select Generic 105-key (Intl) PC' | debconf-set-selections
echo 'samba-common samba-common/dhcp boolean true' | debconf-set-selections

# minissdpd will throw systemd service errors if not configured correctly
NETWINT=$(ip link show | awk '/state UP/ {print $2}' | sed 's/.$//')
if [ -z "$NETWINT" ]; then
    echo -e '\n>>> Cannot find network interface: remove minissdpd' | tee -a "$LOG"
    echo -e '    minissdpd will be re-installed after the dist-upgrade\n' | tee -a "$LOG"
    eval $APT purge minissdpd | tee -a "$LOG"
else
    echo -e "\n>>> Pre-seed minissdpd with network interface: $NETWINT\n" | tee -a "$LOG"
    echo 'minissdpd minissdpd/start_daemon boolean true' | debconf-set-selections
    echo "minissdpd minissdpd/listen string $NETWINT" | debconf-set-selections
fi

echo -e '\n>>> Remove unneeded packages\n' | tee -a "$LOG"
# libreoffice-breeze-dark will brake upgrade of libreoffice
eval $APT purge libreoffice-breeze-dark | tee -a "$LOG"

echo -e '\n>>> Make sure the system is up-to-date\n' | tee -a "$LOG"
apt-get update
eval $APT dist-upgrade | tee -a "$LOG"

echo -e '\n>>> Point sources.list to solydxk-10/buster repositories\n' | tee -a "$LOG"
sed -i 's/ solydxk[0-9e-]* / solydxk-10 /g' /etc/apt/sources.list
sed -i 's/stretch/buster/g' /etc/apt/sources.list
sed -i 's/ testing /buster/g' /etc/apt/sources.list
sed -i 's/testing\//buster\//g' /etc/apt/sources.list
sed -i 's/testing-/buster-/g' /etc/apt/sources.list
cat /etc/apt/sources.list | tee -a "$LOG"

echo -e '\n>>> Upgrade to SolydXK 10/Debian Buster' | tee -a "$LOG"
echo -e '        Fonts and theme change during upgrade but it will be fine after reboot\n' | tee -a "$LOG"
apt-get update
eval $APT upgrade | tee -a "$LOG"
echo -e '\n>>> We need to upgrade systemd before dist-upgrade or else we end up in an unbootable system\n' | tee -a "$LOG"
eval $APT install systemd | tee -a "$LOG"
echo -e '\n>>> Finally run dist-upgrade\n' | tee -a "$LOG"
eval $APT dist-upgrade | tee -a "$LOG"

# If minissdpd was removed, install it now and let the user configure it
if [ -z "$NETWINT" ]; then
    apt-get install minissdpd
fi

echo -e '\n>>> Install/replace packages\n' | tee -a "$LOG"
if [ "$XK" == 'solydx' ]; then
    eval $APT purge solydxee-info gpa | tee -a "$LOG"
    eval $APT install seahorse solydx-system-adjustments-10 | tee -a "$LOG"
else
    eval $APT purge solydkee-info | tee -a "$LOG"
    eval $APT install solydk-system-adjustments-10 | tee -a "$LOG"
fi

# Cleanup
echo
echo -e '>>> Do you want to remove unavailable and orphaned packages?\n\n' \
'   WARNING: this will remove all packages not found in the current repositories\n' \
'            and it will remove all orphaned packages.\n\n'
read -p 'Do you want to continue  (y/N)?' ANSWER
case "$ANSWER" in 
    y|Y )
        if [ "$NOTORPHAN" != '*' ]; then
            echo -e '\n>>> Remove unavailable packages only when not manually held back\n' | tee -a "$LOG"
            for PCK in $(env LANG=C apt-show-versions | grep 'available' | cut -d':' -f1); do
                REMOVE=true
                for HELDPCK in $(env LANG=C dpkg --get-selections | grep hold$ | awk '{print $1}'); do
                    if [ $PCK == $HELDPCK ]; then
                        REMOVE=false
                    fi
                done
                if $REMOVE; then
                    if [[ "$NOTORPHAN" =~ "$PCK" ]] || [ "$NOTORPHAN" == '*' ]; then
                        echo "Not available but keep installed: $PCK" | tee -a "$LOG"
                    else
                        eval $APT purge $PCK | tee -a "$LOG"
                    fi
                fi
            done
            echo -e '\n>>> Removing orphaned packages\n' | tee -a "$LOG"
            EXCL=${NOTORPHAN//,/\/d;/}
            ORPHANED=$(deborphan | sed '/'$EXCL'/d')
            while [ "$ORPHANED" ]; do
                eval $APT purge $ORPHANED | tee -a "$LOG"
                RC=$(dpkg-query -l | sed -n 's/^rc\s*\(\S*\).*/\1/p')
                [ "$RC" ] && eval $APT purge $RC
                ORPHANED=$(deborphan | sed '/'$EXCL':/d')
            done
        fi
    ;;
esac
# Safe to remove
eval $APT autoremove | tee -a "$LOG"
apt-get clean

chown $UNM:$UNM "$LOG"

echo
echo -e '\n>>> Upgrade finished: reboot your system\n' | tee -a "$LOG"
echo "    Log: $LOG"
echo
