#!/usr/bin/bash

set -eou pipefail

# coloring / ugum chooser
source /usr/lib/ujust/ujust.sh

get_config() {
    MOTD_CONFIG_FILE="${MOTD_CONFIG_FILE:-/etc/ublue-os/bling.json}"
    QUERY="$1"
    FALLBACK="$2"
    shift
    shift
    OUTPUT="$(jq -r "$QUERY" "$MOTD_CONFIG_FILE" 2>/dev/null || echo "$FALLBACK")"
    if [ "$OUTPUT" == "null" ] ; then
        echo "$FALLBACK"
        return
    fi
    echo "$OUTPUT"
}


# Exit Handling
function Exiting() {
    printf "%s%sExiting...%s\n" "${red}" "${bold}" "${normal}"
    printf "Rerun script with %s%sujust $BLING_CLI_NAME%s\n" "${blue}" "${bold}" "${normal}"
    exit 0
}

# Trap function
function ctrl_c() {
    printf "\n%s\n" "Signal SIGINT caught"
    Exiting
}

# Brew Bundle Install
function brew-bundle() {
    echo 'Installing bling from Homebrew 🍻🍻🍻'
    brew bundle --file "$BLING_BREW_BUNDLE_PATH"
}

# Pixi Install Global
function pixi-install-global() {
    echo 'Installing bling with pixi (global install) 🐍🐍🐍'

    if [ ! -f "$BLING_PIXI_PACKAGES_FILE" ]; then
        echo "Error: Pixi packages file not found at $BLING_PIXI_PACKAGES_FILE"
        exit 1
    fi

    packages="$(cat "$BLING_PIXI_PACKAGES_FILE" | grep -v '^#' | grep -v '^$' | tr '\n' ' ')"
    
    if [ -z "$packages" ]; then
        echo "Error: No packages found in $BLING_PIXI_PACKAGES_FILE"
    	exit 1
  fi

    pixi global install $packages
}

# Check if bling is already sourced
# 0 for yes
# 1 for no
function is-bling-installed() {
    shell="$1"
    shift

    line=""
    BLING_SCRIPT_SOURCE="bling.sh"
    TARGET_CONFIG_FILE="${HOME}/.bashrc"
    case "${shell}" in
        "fish")
            BLING_SCRIPT_SOURCE="bling.fish"
            TARGET_CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish"
        ;;
        "zsh")
            BLING_SCRIPT_SOURCE="bling.sh"
            TARGET_CONFIG_FILE="${ZDOTDIR:-$HOME}/.zshrc"
        ;;
        "bash")
            BLING_SCRIPT_SOURCE="bling.sh"
            TARGET_CONFIG_FILE="${HOME}/.bashrc"
        ;;
        *)
            echo 'Unknown shell. You are on your own.'
            exit 1
        ;;
    esac
    # Prevents grep erroring out when theres no config file for the shell
    touch "$TARGET_CONFIG_FILE"
    line="$(grep -n "source $BLING_CLI_DIRECTORY/$BLING_SCRIPT_SOURCE" "$TARGET_CONFIG_FILE")"
    line="$(grep -Eo '^[^:]+' <<< "$line")"

    if [[ -n "${line}" ]]; then
        return 0
    fi
    return 1
}

# Add Bling
function add-bling() {
    shell="$1"
    shift
    
    if [[ "${BLING_USE_PIXI}" == "1" ]]; then
        pixi-install-global || Exiting
    else
        brew-bundle || Exiting
    fi

    echo 'Setting up your Shell 🐚🐚🐚'
    case "${shell}" in
        "fish")
            echo 'Adding bling to your config.fish 🐟🐟🐟'
            cat<<EOF >> "${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish"
### bling.fish source start
test -f $BLING_CLI_DIRECTORY/bling.fish && source $BLING_CLI_DIRECTORY/bling.fish
### bling.fish source end
EOF
        ;;
        "zsh")
            echo 'Adding bling to your .zshrc 💤💤💤'
            cat<<EOF >> "${ZDOTDIR:-$HOME}/.zshrc"
### bling.sh source start
test -f $BLING_CLI_DIRECTORY/bling.sh && source $BLING_CLI_DIRECTORY/bling.sh
### bling.sh source end
EOF
        ;;
        "bash")
            echo 'Adding bling to your .bashrc 💥💥💥'
            cat<<EOF >> "${HOME}/.bashrc"
### bling.sh source start
test -f $BLING_CLI_DIRECTORY/bling.sh && source $BLING_CLI_DIRECTORY/bling.sh
### bling.sh source end
EOF
        ;;
        *)
            echo 'Unknown shell. You are on your own.'
            exit 1
        ;;
    esac
}

# Remove bling, handle if old method
function remove-bling() {
    shell="$1"
    shift

    case "${shell}" in
        "fish")
            sed -i '/### bling.fish source start/,/### bling.fish source end/d' \
                "${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish" \
                || \
                line=$(grep -n "source $BLING_CLI_DIRECTORY/bling.fish" \
                "${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish" \
                | grep -Eo '^[^:]+') \
                && \
                sed -i "${line}"d "${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish"
        ;;
        "zsh")
            sed -i '/### bling.sh source start/,/### bling.sh source end/d' \
                "${ZDOTDIR:-$HOME}/.zshrc" \
                || \
                line=$(grep -n "source $BLING_CLI_DIRECTORY/bling.sh" \
                "${ZDOTDIR:-$HOME}/.zshrc" \
                | grep -Eo '^[^:]+') && sed -i "${line}"d \
                "${ZDOTDIR:-$HOME}/.zshrc"
        ;;
        "bash")
            sed -i '/### bling.sh source start/,/### bling.sh source end/d' \
                "${HOME}/.bashrc" \
                || \
                line=$(grep -n "source $BLING_CLI_DIRECTORY/bling.sh" \
                "${HOME}/.bashrc" \
                | grep -Eo '^[^:]+') && sed -i "${line}"d \
                "${HOME}/.bashrc"
        ;;
    esac
}

function main() {
    # Get Shell
    shell=$(basename "$SHELL")
    reentry="$1"
    clear
    if [[ -n "${reentry:-}" ]]; then
        printf "%s%s%s\n\n" "${bold}" "$reentry" "$normal"
    fi
    
    # Check if bling is enabled and display
    printf "Shell:\t%s%s%s%s\n" "${green}" "${bold}" "${shell}" "${normal}"
    if is-bling-installed "${shell}"; then
        printf "Bling:\t%s%sEnabled%s\n" "${green}" "${bold}" "${normal}"
    else
        printf "Bling:\t%s%sDisabled%s\n" "${red}" "${bold}" "${normal}"
    fi
    
    # ugum enable/disable
    CHOICE=$(Choose enable disable cancel)
    
    # Enable/Disable. Recurse if bad option.
    case "${CHOICE,,}" in
        "enable")
            if is-bling-installed "${shell}"; then
                main "Bling is already configured ..."
            fi
            trap ctrl_c SIGINT
            add-bling "${shell}"
            printf "%s%sInstallation Complete%s ... please close and reopen your terminal!" "${green}" "${bold}" "${normal}"
	    printf "Check out the documentation at: https://docs.projectbluefin.io/bluefin-dx#bluefin-cli\n"
	    exit 0
        ;;
        "disable")
            if ! is-bling-installed "${shell}"; then
                main "Bling is not yet configured ..."
            fi
            trap ctrl_c SIGINT
            remove-bling "${shell}"
            printf "%s%sBling Removed%s ... please close and reopen your terminal\n" "${red}" "${bold}" "${normal}"
            exit 0
        ;;
        *)
            Exiting
        ;;
    esac
}

BLING_CLI_NAME="$(get_config '."bling-cli-name"' "bluefin-cli")"
BLING_CLI_DIRECTORY="$(get_config '."bling-cli-path"' "/usr/share/ublue-os/bling")"
BLING_BREW_BUNDLE_PATH="$(get_config '."bling-brew-bundle-path"' "/usr/share/ublue-os/homebrew/$BLING_CLI_NAME.Brewfile")"
BLING_PIXI_PACKAGES_FILE="$(get_config '."bling-pixi-package-path"' "/usr/share/ublue-os/bling/${BLING_CLI_NAME}.pixi.list")"
BLING_USE_PIXI="$(get_config '."use-pixi-bling"' "0")"

# Entrypoint
main ""
