#!/usr/bin/env bash

REPO_URL='ppa.cuwb.io'
REPO_NAME='official'

CUWB_SERVER_DB_DIR='/var/lib/cuwb/server/db-files/uwb/saved/'

# util function to make wait for dpkg lock
function waitForDpkg() {
    while fuser /var/lib/dpkg/lock >/dev/null 2>&1
        do sleep 1
    done
}

# check if user is in sudoers
if groups $(whoami) | grep &>/dev/null '\bsudo\b'; then
    echo 'User is a sudoer'
else
    echo 'You must belong to the sudo group to complete installation of CUWB Package Installer'
    exit 1
fi

# check if current env headless or not
HEADLESS=true
waitForDpkg
if dpkg -l ubuntu-desktop &>/dev/null; then
    echo 'GUI environment detected'
    HEADLESS=false
fi

# check for 20.04, 22.04, or 24.04
DISTRO=$(lsb_release -cs)
echo "Detected distribution: $DISTRO"
if [[ $DISTRO != 'focal' && $DISTRO != 'jammy' && $DISTRO != 'noble' ]]; then
    echo 'This distribution is not currently supported. Bailing!'
    exit 1
fi

# PPA to sources.list install logic
function add_ppa_if_needed() {
    echo 'Adding Ciholas key'
    sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 13FB78B5
    if [ $? -ne 0 ]; then
        echo 'Adding Ciholas key failed via hkp. You may be behind a proxy. Attempting alternate route.'
        wget -qO - https://cuwb.io/ciholas.pgp | sudo apt-key add -
        if [ $? -ne 0 ]; then
            echo 'Adding Ciholas trusted key failed. Installation will halt. Please contact cuwb.support@ciholas.com for assistance with the above log output.'
            exit 1
        fi
    fi
    grep ^ /etc/apt/sources.list /etc/apt/sources.list.d/* | grep "$REPO_URL/$REPO_NAME" &>/dev/null
    if [ $? -ne 0 ]; then
        echo 'Adding CUWB PPA'
        source /etc/lsb-release
        echo "deb [arch=amd64] https://$REPO_URL/$REPO_NAME/ $DISTRIB_CODENAME main" |
            sudo tee /etc/apt/sources.list.d/cuwb.list
    fi
}

# Functions invoked for installing packages
# CUWB Manager Install Package
function install_cuwb_manager() {
    waitForDpkg
    CUWB_SERVER_CHECK_CMD=$(dpkg -s cuwb-server | grep Status | grep ' install ok')
    CUWB_SERVER_CHECK=$?
    NAPPER_CHECK_CMD=$(dpkg -s napper &>/dev/null)
    NAPPER_CHECK=$?
    if [[ $CUWB_SERVER_CHECK -eq 0 || $NAPPER_CHECK -eq 0 ]]; then
        if (whiptail --title "CUWB Package Installer" --yesno \
            "CUWB Server & Napper are deprecated. They will conflict with CUWB Manager. Would you like to remove them?" 8 78) then
            # Check and remove cuwb-server
            if [ $CUWB_SERVER_CHECK -eq 0 ]; then
                echo 'CUWB Server is installed. Removing...'
                waitForDpkg
                sudo apt-get remove -y '^cuwb-server' # We do not purge so the saved DBs are preserved and regex for suffixed forks
            fi
            # Check and purge napper
            if [ $NAPPER_CHECK -eq 0 ]; then
                waitForDpkg
                echo 'Napper is installed. Purging...'
                sudo apt-get purge -y napper
            fi
        else
            echo 'User opted not to remove cuwb-server and napper. Attempting to install cuwb-manager anyway...'
        fi
    fi
    waitForDpkg
    echo 'Installing CUWB Manager'
    sudo apt install -y --allow-downgrades cuwb-manager=5.1.0-cuwb5.1.0+$DISTRO
}

# CDP Logger
function install_cdp_logger() {
    waitForDpkg
    echo 'Installing CDP Logger'
    sudo apt install -y --allow-downgrades cdp-logger=1.6.0
}

# CDP Logger
function install_cuwb_usb_interface() {
    waitForDpkg
    echo 'Installing CUWB USB Interface'
    sudo apt install -y --allow-downgrades cuwb-usb-interface=1.2.0
}

# CUWB Viewer
function install_cuwb_viewer() {
    waitForDpkg
    echo 'Installing CUWB Viewer'
    sudo apt install -y --allow-downgrades cuwb-viewer=2.2.1
}

# CUWB Firmware
function install_cuwb_firmware() {
    waitForDpkg
    echo 'Installing CUWB Firmware'
    sudo apt install -y --allow-downgrades cuwb-firmware-an302=6.3.0-cuwb5.1.0 cuwb-firmware-pt301=6.3.0-cuwb5.1.0
}

# Welcome message
whiptail --title "CUWB Package Installer" --msgbox "Welcome to the CUWB Package Installer!" 8 78

# Ask about code word for repo select
if (whiptail --title "CUWB Package Installer" --yesno "Would you like to use the official/default repository?\nSelect 'NO' for non-standard installation." 8 78) then
    echo "User selected Yes, exit status was $?."
else
    echo "User selected No, exit status was $?."
    REPO_NAME='Secret'
fi

# save references to stdout and stderr because whiptail necessitates doing some return through stderr
exec {STDOUTBACK}>&1
exec {STDERRBACK}>&2

# Prompt for repo name secret if official not desired
if [ "$REPO_NAME" != 'official' ]; then
    REPO_NAME=$(whiptail --inputbox "Type the non-official repository secret phrase below" 8 78 official \
                --title "CUWB Package Repo Set" 3>&1 1>&2 2>&3)
    if [ $? = 0 ]; then
        echo "User chose the following repo: " $REPO_NAME
    else
        echo "User selected Cancel. Proceeding with official repo."
        REPO_NAME='official'
    fi
fi

# App packages multi-select
PACKAGES=$(whiptail --title "CUWB Applications selection" --checklist \
    "Choose from the following packages:\nUse arrow keys to move\nUse the Space key to select\nTab to OK or Cancel" 20 78 4 \
    "CUWB Manager" "Primary package used for CUWB RTLS system" ON \
    "CUWB Firmware" "Firmware packages used for CUWB RTLS system" ON  \
    "CUWB Viewer" "3D visualization program for the CUWB RTLS" OFF \
    "CDP Logger" "Ciholas Data Protocol Logger/Player" OFF \
    "CUWB USB Driver" "USB CDP interface" OFF 3>&1 1>&2 2>&3)

# Restore fds
exec 1>&$STDOUTBACK
exec 2>&$STDERRBACK

# Close temporal fds
exec {STDOUTBACK}>&-
exec {STDERRBACK}>&-

# Install packages if requested
if [ "${PACKAGES[0]}" != '' ]; then
    echo 'We are going to install the desired packages. This may ask for your password.'
    add_ppa_if_needed
    sudo apt update
    IFS='"' # Split whiptail return array by " and not spaces
    waitForDpkg
    for package in $PACKAGES; do
        case "$package" in
            'CDP Logger') install_cdp_logger
            ;;
            'CUWB Manager') install_cuwb_manager
            ;;
            'CUWB USB Driver') install_cuwb_usb_interface
            ;;
            'CUWB Viewer') install_cuwb_viewer
            ;;
            'CUWB Firmware') install_cuwb_firmware
            ;;
            '') # noop
            ;;
            *) echo 'Unknown package'
            ;;
        esac
    done
else
    echo 'No packages selected. Exiting...'
    exit 0
fi

exit 0
