#!/bin/bash
#
# prepare-linux.sh - Linux Initial Configuration Script
#
# Purpose: Perform basic preparatory configuration when first using Linux to enable further configurations
# Features:
#   1. Detect or specify distribution type (Arch/Debian/Fedora)
#   2. Install common packages
#   3. Set environment variables and hostname
#   4. Configure Git
#   5. Change default Shell to zsh
#

VERSION="1.0.2"
SCRIPT_NAME="$(basename "$0")"
SCRIPT_FILE="$(readlink -f "$0")"
SCRIPT_FOLDER="$(cd "$(dirname "$0")" && readlink -f "$(pwd)")"

# Parse command line arguments
DISTRO=""
SHOW_HELP=false
SHOW_VERSION=false

while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            SHOW_HELP=true
            shift
            ;;
        -v|--version)
            SHOW_VERSION=true
            shift
            ;;
        --arch)
            DISTRO="Arch based"
            shift
            ;;
        --debian)
            DISTRO="Debian based"
            shift
            ;;
        --fedora)
            DISTRO="Fedora based"
            shift
            ;;
        *)
            echo "Unknown parameter: $1"
            SHOW_HELP=true
            shift
            ;;
    esac
done

# Display version information
if [ "$SHOW_VERSION" = true ]; then
    echo "$SCRIPT_NAME version $VERSION"
    exit 0
fi

# Display help information
if [ "$SHOW_HELP" = true ]; then
    echo "Usage: $SCRIPT_NAME [options]"
    echo ""
    echo "Options:"
    echo "  -h, --help     Display this help information"
    echo "  -v, --version  Display version information"
    echo "  --arch         Specify as Arch-based distribution"
    echo "  --debian       Specify as Debian-based distribution"
    echo "  --fedora       Specify as Fedora-based distribution"
    echo ""
    echo "If no distribution is specified, the script will let the user choose through an interactive menu."
    exit 0
fi

PKGS_ONCE=("git" "whiptail" "ncdu" "duf" "zsh" "zip" "unzip" "unrar" "p7zip" "dtrx" "python3" "ranger" "mc" "rsync" "figlet" "htop" "nano" "tree" "screen" "ffmpeg" "axel" "qalc")
PKGS_TRY=("ssh" "openssh" "eza" "exa" "python3-pip" "python-pip" "rar" "p7zip-full" "shellcheck" "rename" "perl-rename")

ENVBASE="$(cat <<-EOF
GITAUTO="$HOME/Documents/git"
SYSCFG="$HOME/Documents/git/gitlab.pi/gem/system-config"
SHOW_FIGLET_HOSTNAME="1"
EOF
)"

HOSTSBASE="$(cat <<-EOF
192.168.1.10    pve.me
192.168.1.9     cube.me gitlab.pi
EOF
)"

function pkg_install() {
    distro="$1"
    shift
    pkgs=("$@")
    if [[ -n "$distro" && ${#pkgs[@]} -gt 0 ]]; then
        echo -e "\033[32mInstalling package(s) \033[0m${pkgs[*]}\033[32m for distro \033[0m$distro\033[0m"
        if [ "$distro" = "Arch based" ]; then
            sudo pacman -S --noconfirm "${pkgs[@]}"
        elif [ "$distro" = "Debian based" ]; then
            sudo apt install -y "${pkgs[@]}"
        elif [ "$distro" = "Fedora based" ]; then
            sudo dnf install -y "${pkgs[@]}"
        fi
    else
        echo -e "\033[31mERROR: Failed to install packages for distro $distro\033[0m"
        return 1
    fi
}

# If no distribution is specified via parameters, select through an interactive menu
if [ -z "$DISTRO" ]; then
    DISTRO=$(whiptail --title "[$SCRIPT_NAME] Distro" --menu "Choose the Linux Distro to continue:" 18 60 4 \
        "Arch based" "" \
        "Debian based" "" \
        "Fedora based" "" \
        3>&1 1>&2 2>&3)
    exitstatus=$?
    if [ $exitstatus != 0 ]; then
        echo "User cancelled operation"
        exit 1
    fi
else
    echo -e "\033[32mDistribution specified:\033[0m $DISTRO"
fi

echo -e "\033[32mDistro\033[0m: $DISTRO"

## INSTALL PACKAGES
echo -e "\033[1;33mInstalling Packages...\033[0m"
pkg_install "$DISTRO" "${PKGS_ONCE[@]}"

for pkg in "${PKGS_TRY[@]}"; do
    pkg_install "$DISTRO" "$pkg"
done

## ENV SETUP
echo -e "\033[1;33mSetting-up Environment...\033[0m"
grep -qxF "$ENVBASE" /etc/environment || echo "$ENVBASE" | sudo tee --append /etc/environment
grep -qxF "$HOSTSBASE" /etc/hosts || echo "$HOSTSBASE" | sudo tee --append /etc/hosts
MAKEPATH=("$HOME/Documents/git/gitlab.pi")
for mp in "${MAKEPATH[@]}"; do
    if [ ! -e "$mp" ]; then
        echo -e "\033[1;32mMaking directory $\033[0m$mp\033[0m"
        if ! mkdir -p "$mp" 2>/dev/null; then
            sudo mkdir -p "$mp"
        fi
    fi
done
NEW_HOSTNAME="$(whiptail --title "[$SCRIPT_NAME] Hostname" --inputbox "Hostname for your computer" 18 60 "$(hostname)" 3>&1 1>&2 2>&3)"
if [ -n "$NEW_HOSTNAME" ]; then
    echo "$NEW_HOSTNAME" | sudo tee /etc/hostname
fi
if [ -e /usr/local/bin/python3 ]; then
    sudo rm -f /usr/local/bin/python3
fi
sudo ln -s /usr/bin/python3 /usr/local/bin/

## CHANGE SHELL
zsh_path=$(which zsh | tr ' ' '\n' | head -n 1)
if [ -n "$zsh_path" ]; then
    echo -e "\033[1;33mChanging SHELL...\033[0m"
    chsh -s "$zsh_path"
    sudo chsh -s "$zsh_path"
fi

## GIT CONFIG
echo -e "\033[1;33mConfiguring Git...\033[0m"
G_UNAME="$(whiptail --title "[$SCRIPT_NAME] Git User" --inputbox "" 15 60 "Ezra" 3>&1 1>&2 2>&3)"
if [ -n "$G_UNAME" ]; then
    git config --global user.name "$G_UNAME"
fi
G_EMAIL="$(whiptail --title "[$SCRIPT_NAME] Git E-mail" --inputbox "" 15 60 "ezra@hotodogo.com" 3>&1 1>&2 2>&3)"
if [ -n "$G_EMAIL" ]; then
    git config --global user.email "$G_EMAIL"
    git config --global pull.rebase false
    git config --global credential.helper store
    git config --global core.quotepath false
    git config --global http.postBuffer 524288000
fi
G_EDITOR=$(whiptail --title "[$SCRIPT_NAME] Git Editor" --menu "Choose the editor you use:" 16 60 8 \
    "nano" "" \
    "micro" "" \
    "nvim" "" \
    "code" "" \
    "emacs" "" \
    "mousepad" "" \
    "gedit" "" \
    3>&1 1>&2 2>&3)
exitstatus_git=$?
if [ $exitstatus_git = 0 ]; then
    git config --global core.editor "$G_EDITOR"
fi

echo -e "\033[1;33mChanging SHELL...\033[0m"
