#!/usr/bin/env bash
#
# install.sh
#
# Installs dotfiles and packages for my setup.
# Needs to be invoked from containing dotfile directory to work correctly.
#
# Will first install yay, then all my used packages (read from bootstrap/packages.txt)
#
# Finally, symlinks all dotfiles into their correct locations using stow

bootstrap_dir="${BOOTSTRAP_DIRECTORY:-./bootstrap}"

main() {
    local cmd=""
    local ret=0

    case "$1" in
    -v | --version)
        printf "Personal system bootstrap script.\n\nby Marty Oehme\n\nv0.2\n"
        ;;
    -h | --help)
        printf "Usage: install [-f|--force][-v|--version][-h|--help]\n\n-f     Do not ask for any confirmations but force update and installation.\n"
        ;;
    -f | --force)
        install true
        ;;
    *)
        install false
        ;;
    esac
    shift

    $cmd "$@"
    ret=$((ret + $?))
    exit $ret
}

# takes default value (y/n), question, abort message as arguments
# automatically answers yes if unattended install
check_consent() {
    if [ "$UNATTENDED" == "true" ]; then
        true
    else
        [[ "$1" == "y" ]] && default_consent="[Y/n]" || default_consent="[y/N]"
        printf "%b %b " "$2" "$default_consent"
        read -r answer
        if [[ "$1" == "n" ]] && [[ "$answer" != y* ]]; then
            printf "%s\n" "$3"
            false
        elif [[ "$1" == "y" ]] && [[ "$answer" == n* ]]; then
            printf "%s\n" "$3"
            false
        else
            true
        fi
    fi
}

entry_question() {
    check_consent n "This will take a while and install many packages and link dotfiles all over the place depending on your selections.\nYou need to be in the base directory of the dotfiles repository.\nProceed?" "Aborting." || exit
}

enable_git_hooks() {
    check_consent y "Should we enable git hooks for this repository, so that installed packages are automatically compared when committing?" "Not changing repository settings." || return
    git config --local core.hooksPath .githooks/
    echo "Changed repository settings."
}

stow_dotfiles() {
    check_consent y "Link home directory dot files?" "Not linking dotfiles." || return
    # get all top level directories, remove their slashes and dots
    # finally get rid of .dot-directories, since they are for the repo not for my homedir
    targets="$(find . -maxdepth 1 -type d | sed -e 's/^\.\/\(.*\)$/\1/' | sed -e '/^\./d')"

    # shellcheck disable=2086
    # -- for some reason stow only works with unqoted var expansion
    stow -R ${targets} 2> >(grep -v 'Absolute/relative mismatch between Stow dir' 1>&2)
    echo "Linked dotfiles."
}

run_elevated() {
    if command -v doas >/dev/null 2>&1; then
        doas "$@"
    elif command -v sudo >/dev/null 2>&1; then
        sudo "$@"
    fi
}

stow_system_packages() {
    check_consent n "Link system settings files? This will require sudo access and may overwrite existing files." "Not touching system files." || return
    if [ -e "/etc/pacman.conf" ]; then
        check_consent n "Found an existing pacman.conf file, installation will error if it exists. Remove file?" && run_elevated rm "/etc/pacman.conf"
    fi
    run_elevated stow --dir="$bootstrap_dir" --target="/" -R system-packages/
    echo "Linked system files."
}

install_packages() {
    check_consent n "Install pre-designated packages? This will take a while, install a lot of packages and require super user privileges." "Not installing packages." || return
    if ! "$UNATTENDED"; then
        "$bootstrap_dir"/install_packages.sh
    else
        "$bootstrap_dir"/install_packages.sh -f
    fi
    echo "Installed packages."
}

install() {
    UNATTENDED=$1
    if ! "$UNATTENDED"; then
        entry_question
    fi

    echo "====================== BEGINNING SYSTEM FILE MANAGEMENT ============================="
    stow_system_packages

    echo "====================== BEGINNING PACKAGE INSTALLATION ============================="
    install_packages

    echo "=================== BEGINNING DOTFILE MANAGEMENT =========================="
    stow_dotfiles

    echo "================== ENABLING GIT REPOSITORY HOOKS =========================="
    enable_git_hooks

    echo "====================== INSTALLATION FINISHED =============================="
    exit 0
}

main "$@"
