#!/usr/bin/env bash

# Quick script to handle upgrading Debian based systems

# A better class of script...
set -o errexit          # Exit on most errors (see the manual)
set -o errtrace         # Make sure any error trap is inherited
set -o nounset          # Disallow expansion of unset variables
set -o pipefail         # Use last non-zero exit code in a pipeline
#set -o xtrace          # Trace the execution of the script (debug)

# DESC: Find some important paths we need before script_init() is called
# ARGS: None
# OUTS: $script_real_path: The full canonicalized path to the script
#       $script_real_dir: The canonicalized directory path of the script
#       $script_real_name: The canonicalized file name of the script
#       $dotfiles_path: The dotfiles directory path
#       $dotfiles_name: The dotfiles directory name
# shellcheck disable=SC2034
function early_init() {
    # Determine the physical directory this script resides in. This approach is
    # necessarily clumsy as simple methods like "readlink -f" and "realpath"
    # are not platform independent. We have to work on Linux, BSD, OS X, etc...
    script_real_path="$(perl -MCwd -le 'print Cwd::abs_path(shift)' "${BASH_SOURCE[0]}")"
    script_real_dir="$(dirname "$script_real_path")"
    script_real_name="$(basename "$script_real_path")"
    readonly script_real_path script_real_dir script_real_name

    # Dotfiles directory path & name
    dotfiles_path="$(cd -P "$script_real_dir/../../" && pwd)"
    dotfiles_name="$(basename "$dotfiles_path")"
    readonly dotfiles_path dotfiles_name
}

# DESC: Main control flow
# ARGS: $@ (optional): Arguments provided to the script
function main() {
    early_init

    # shellcheck source=scripts/bin/bash-template.sh
    source "$script_real_dir/bash-template.sh"

    trap script_trap_err ERR
    trap script_trap_exit EXIT

    script_init "$@"
    colour_init

    # shellcheck disable=SC2119,SC2310
    if ! check_superuser; then
        script_exit 'Superuser access (via root or sudo) is required.' 1
    fi

    check_binary 'dpkg' 'fatal'

    pretty_print '*** Updating package index files ...'
    run_as_root apt-get update > /dev/null
    echo

    pretty_print '*** Upgrading installed packages ...'
    run_as_root apt-get dist-upgrade
    echo

    pretty_print '*** Removing redundant packages ...'
    run_as_root apt-get autoremove
    echo

    pkgs_rc="$(dpkg --get-selections | grep 'deinstall' | cut -f1 || true)"
    if [[ -n $pkgs_rc ]]; then
        pretty_print '*** Purging removed packages ...'
        # shellcheck disable=SC2086
        run_as_root apt-get purge $pkgs_rc
        echo
    fi

    pretty_print '*** Cleaning local repository ...'
    sudo apt-get autoclean
    echo

    pkgs_num="$(dpkg --get-selections | wc -l)"
    pretty_print "*** Total installed packages: $pkgs_num"
    echo

    pretty_print '*** Done!'
}

# Perform system update
main "$@"

# vim: syntax=sh cc=80 tw=79 ts=4 sw=4 sts=4 et sr
