#!/bin/bash
# todo:
##   packages to add:
##   x enable start services: xrdp apache2 avahi-service
##   x run customscripts
##   make less interactive
###      visudo
###      su user
##  x reboot

# set safety optinonz
set -o errexit # fail on error
set -o errtrace # run trace on error
set -o pipefail # fail on pipe fail
set -o nounset # fail on unset var

# packages
new_packages=(gawk curl wget git gh build-essential scrypt openssl argon2 qbittorrent xfce4 gparted xrdp xz-utils 7zip zip unzip gzip apache2 php php-cli php-bz2 php-crypt-gpg php-curl php-db php-doc php-email-validator cowsay iotop iptraf-ng gh btop htop screen byobu wget thefuck lynx zip unzip 7zip net-tools clamav php restic cifs-utils detox fdupes ffmpeg ripgrep avahi-daemon libnss-mdns xxd libimage-exiftool-perl ffuf wireshark hashcat snap pipx restic firefox)

# user info
new_username="princesspi"
groups_username=("tty" "dialout" "plugdev" "sudo" "www-data")
home_username="/home/${new_username}"

# services shit
services_to_enable=("ssh" "apache2" "xrdp" "avahi-daemon")
services_to_disable=("nginx")

# save here to use in error_handle function
num_of_args="$#"
all_args="$@"

# Define the cleanup function
error_handle() {
    # CRITICAL: Capture the exit status code before ANY other command runs
    local exit_code=$?
    local script_path="$(realpath $0)"
    local hr='===================================================='
    echo
    echo $hr
    echo -e "🚨 \033[0;31m FATAL ERROR DETECTED \033[0m"
    echo $hr
    echo "-> Script            : $0"
    echo "-> Num Script Args   : $num_of_args"
    echo "-> Script Args       : $all_args"
    echo "-> Shell             : $SHELL"
    echo "-> Script Path       : $script_path"
    echo "-> Script (full)     : $SHELL $script_path $all_args"
    echo "-> User              : $USER"
    echo "-> Working Directory : $PWD"
    echo "-> Failed Command    : $BASH_COMMAND"
    echo "-> Line Number       : $LINENO"
    echo "-> Exit Status       : $exit_code"
    echo "-> Seconds Elapsed   : $SECONDS"
    echo "-> Date Failed       : $(date)"
    # Generate a professional, clean stack traceback
    echo "-> Stack Trace"
    printf "\t" # to intent da stack trace
    local frame=0
        # Loop backwards through the function execution stack array
    while caller $frame; do
        printf "\t" # to indenet da stack trace
        frame=$((frame + 1))
    done

    # closing niceties
    echo
    echo $hr
    echo

    # exit with last failcode
    exit "$exit_code"
}

trap error_handle ERR

# to give pass/fail output from da commmands
## usage like checkcode $?
checkcode () {
    if [ -z "$1" ]; then
        echo -e "\n\e[31mERROR!\033[0m chkcode missing return code paramater\n"
        exit 1
    else
        retcode=$1
    fi

    if [ $retcode -ne 0 ]; then
        echo -e "\t\e[31mERROR!\033[0m Response Code: $retcode"
    else
        echo -e '\t\e[1;32mOK!\e[0m'
    fi
}

reload_shell() {
    echo "reload_shell: START"
    echo "reload_shell: sourcing to $home_username/.bashrc"
    source "$home_username/.bashrc"
    checkcode $?
    echo "reload_shell: reloading shell"
    exec "$SHELL"
    checkcode $?
    echo "reload_shell: FINISHED"
}

reset_root() {
    echo "reset_root: START"
    echo "reset_root: change password"
    sudo passwd root
    checkcode $?
    echo "reset_root: FINISHED"
}

user() {
    echo "user: START"
    echo "user: create $new_username"
    useradd "$new_username"
    checkcode $?
    echo "user: adding groups"
    for group in "${groups_username[@]}"; do
        echo "user: adding $new_username to group $group"
        usermod -aG $group $new_username &> /dev/null
        checkcode $?
    done
    echo "user: FINISHED"
}

apt() { 
    echo "apt: START"
    echo "apt: updating"
    sudo apt update &> /dev/null
    checkcode $?
    echo "apt: running dist-upgrade"
    sudo apt dist-upgrade -y &> /dev/null
    checkcode $?
    echo "apt: install packages"
    sudo apt install -y "${new_packages[@]}" &> /dev/null
    checkcode $?
    sudo snap install urh
    checkcode $?
    echo "apt: autoremoving"   
    sudo apt autoremove -y &> /dev/null
    checkcode $?
    echo "apt: FINISHED"
}

pyenv() {
    echo "pyenv: START"
    echo "pyenv: installin"
    curl -fsSL https://pyenv.run | bash &> /dev/null
    checkcode $?
    echo "pyenv: adding exports to $home_username/.bashrc" 
    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> "$home_username/.bashrc"
    checkcode $?
    echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> "$home_username/.bashrc"
    checkcode $?
    echo 'eval "$(pyenv init -)"' >> "$home_username/.bashrc"
    checkcode $?
    echo "pyenv: sourcing to $home_username/.bashrc"
    source "$home_username/.bashrc"
    checkcode $?
    echo "pyenv: installing latest python3"
    latest_python=$(pyenv install --list | grep -E '^[[:space:]]*3\.[0-9]+\.[0-9]+$' | tail -1 | tr -d '[:space:]')
    if [ -z "$latest_python" ]; then
        echo "pyenv: could not detect latest Python 3 version"
        exit 1
    fi
    pyenv install "$latest_python" &> /dev/null
    checkcode $?
    echo "pyenv: setting latest python3 as global"
    pyenv global "$latest_python" &> /dev/null
    checkcode $?
    reload_shell
    echo "pyenv: FINISHED"
}

blesh() {
    echo "ble.sh: START"
    echo "ble.sh: changing directory to /tmp"
    cd /tmp
    checkcode $?
    echo "ble.sh: downloading"
    git clone --recursive --depth 1 --shallow-submodules --single-branch -b master https://github.com/akinomyoga/ble.sh.git &> /dev/null
    checkcode $?
    echo "ble.sh: building and installing"
    make -C ble.sh install PREFIX=$home_username/.local &> /dev/null
    checkcode $?
    echo "ble.sh: setting up $home_username/.bashrc file"
    echo '# ble.sh' >> $home_username/.bashrc
    checkcode $?
    echo 'source -- $home_username/.local/share/blesh/ble.sh' >> $home_username/.bashrc
    checkcode $?
    reload_shell
    echo "ble.sh: FINISHED"
}

wordists() {
    echo "wordlists: START"
    echo "wordlists: making $home_username/wordlists dir"
    mkdir -p $home_username/wordlists &> /dev/null
    checkcode $?
    echo "wordlists: downloading seclists to $home_username/wordlists" 
    git clone --single-branch https://github.com/danielmiessler/SecLists.git $home_username/wordlists/SecLists &> /dev/null
    # todo: finish
    echo "wordlists: FINISHED"
}

services() {
    echo "services: START"
    echo "services: disable"
    for service in "${services_to_disable[@]}"; do
        echo "services: disabling $service"
        sudo systemctl disable "$service"
        checkcode $?
        echo "services: stopping $service"
        sudo systemctl stop "$service"
        checkcode $?
    done
    echo "services: enable"
    for service in "${services_to_enable[@]}"; do
        echo "services: enabling $service"
        sudo systemctl enable "$service" &> /dev/null
        checkcode $?
        echo "services: starting $service"
        sudo systemctl start "$service" &> /dev/null
        checkcode $?
    done
    echo "services: FINISHED"
}

customscripts() {
    echo "customscripts: START"
    script="/tmp/install_script.sh"
    echo "customscripts: downloading general-scripts-and-system-ssssssetup installer"
    curl -s https://raw.githubusercontent.com/PrincessPi3/general-scripts-and-system-ssssssetup/refs/heads/main/customscripts/install_script.sh > "$script"
    checkcode $?
    echo "customscripts: making $script executable"
    chmod +x "$script"
    checkcode $?
    echo "customscripts: running $script"
    bash -c "$script full"
    checkcode $?
    echo "customscripts: running configure_webhook.sh full"
    bash /usr/share/customscripts/configure_webhook.sh full
    checkcode $?
    echo "customscripts: updating user .bashrc"
    echo 'export PATH="$PATH:/usr/share/customscripts"' >> "$home_username/.bashrc"
    checkcode $?
    reload_shell
}

reboot() {
    echo "reboot: START"
    echo "reboot: setting to reboot in one minute"
    sudo shutdown -r +1
    echo "reboot: FINISHED"
}

# run in order
user
apt
pyenv
blesh
wordlists
services
customscripts
reboot