#!/usr/bin/env bash
set -euo pipefail

platform=$(uname -ms)

if [[ ${OS:-} = Windows_NT ]]; then
  if [[ $platform != MINGW64* ]]; then
    powershell -c "irm https://glesha.toxdes.com/install.ps1|iex"
    exit $?
  fi
fi

# Reset
Color_Off=''

# Regular Colors
Red=''
Green=''
Dim='' # White

# Bold
Bold_White=''
Bold_Green=''

if [[ -t 1 ]]; then
    # Reset
    Color_Off='\033[0m' # Text Reset

    # Regular Colors
    Red='\033[0;31m'   # Red
    Green='\033[0;32m' # Green
    Dim='\033[0;2m'    # White

    # Bold
    Bold_Green='\033[1;32m' # Bold Green
    Bold_White='\033[1m'    # Bold White
fi

error() {
    echo -e "${Red}error${Color_Off}:" "$@" >&2
    exit 1
}

info() {
    echo -e "${Dim}$@ ${Color_Off}"
}

info_bold() {
    echo -e "${Bold_White}$@ ${Color_Off}"
}

success() {
    echo -e "${Green}$@ ${Color_Off}"
}

command -v curl >/dev/null ||
    error 'curl is required to install glesha'

command -v tar >/dev/null || command -v unzip >/dev/null ||
    error 'tar or unzip is required to install glesha'

# Determine the correct release filename based on OS and Architecture
BASE_URL="https://github.com/toxdes/glesha/releases/latest/download"

OS=$(uname -s)
ARCH=$(uname -m)

case "${OS}" in
    "Linux")
        case "${ARCH}" in
            "x86_64" | "amd64")
                FILENAME="linux_amd64.tar.gz"
                ARCHIVE_TYPE="tar.gz"
                ;;
            "i386" | "i686")
                FILENAME="linux_386.tar.gz"
                ARCHIVE_TYPE="tar.gz"
                ;;
            "aarch64" | "arm64")
                FILENAME="linux_arm64.tar.gz"
                ARCHIVE_TYPE="tar.gz"
                ;;
            "armv7l" | "armhf")
                FILENAME="linux_arm_v7.tar.gz"
                ARCHIVE_TYPE="tar.gz"
                ;;
            *)
                error "Unsupported Linux architecture: ${ARCH}"
                ;;
        esac
        ;;
    "Darwin")
        case "${ARCH}" in
            "x86_64")
                FILENAME="darwin_amd64.zip"
                ARCHIVE_TYPE="zip"
                ;;
            "arm64")
                FILENAME="darwin_arm64.zip"
                ARCHIVE_TYPE="zip"
                ;;
            *)
                error "Unsupported macOS architecture: ${ARCH}"
                ;;
        esac
        ;;
    "FreeBSD")
        case "${ARCH}" in
            "x86_64" | "amd64")
                FILENAME="freebsd_amd64.tar.gz"
                ARCHIVE_TYPE="tar.gz"
                ;;
            "aarch64" | "arm64")
                FILENAME="freebsd_arm64.tar.gz"
                ARCHIVE_TYPE="tar.gz"
                ;;
            *)
                error "Unsupported FreeBSD architecture: ${ARCH}"
                ;;
        esac
        ;;
    "MINGW"* | "CYGWIN"* | "MSYS"*)
        case "${ARCH}" in
            "x86_64" | "amd64")
                FILENAME="windows_amd64.zip"
                ARCHIVE_TYPE="zip"
                ;;
            "i686" | "i386")
                FILENAME="windows_386.zip"
                ARCHIVE_TYPE="zip"
                ;;
            "aarch64" | "arm64")
                FILENAME="windows_arm64.zip"
                ARCHIVE_TYPE="zip"
                ;;
            *)
                error "Unsupported Windows architecture: ${ARCH}"
                ;;
        esac
        ;;
    *)
        error "Unsupported operating system: ${OS}"
        ;;
esac

DOWNLOAD_URL="${BASE_URL}/${FILENAME}"

install_env=GLESHA_INSTALL
bin_env=\$$install_env/bin

install_dir=${!install_env:-$HOME/.glesha}
bin_dir=$install_dir/bin
exe=$bin_dir/glesha

if [[ ! -d $bin_dir ]]; then
    info "[+] Creating install directory \"$bin_dir\""
    mkdir -p "$bin_dir" ||
        error "Failed to create install directory \"$bin_dir\""
fi

info "[+] Downloading glesha"
curl --fail --location --progress-bar --output "$exe.archive" "$DOWNLOAD_URL" ||
    error "Failed to download glesha from \"$DOWNLOAD_URL\""

info "[+] Extracting glesha"
case "${ARCHIVE_TYPE}" in
    tar.gz)
        tar -xzf "$exe.archive" -C "$bin_dir" ||
            error 'Failed to extract glesha'
        ;;
    zip)
        unzip -oq "$exe.archive" -d "$bin_dir" ||
            error 'Failed to extract glesha'
        ;;
esac

info "[+] Setting permissions on glesha executable"
chmod +x "$exe" ||
    error 'Failed to set permissions on glesha executable'

rm "$exe.archive"

tildify() {
    if [[ $1 = $HOME/* ]]; then
        local replacement=\~/

        echo "${1/$HOME\//$replacement}"
    else
        echo "$1"
    fi
}

success "glesha was installed successfully to $Bold_Green$(tildify "$exe")"

if command -v glesha >/dev/null; then
    echo "Run 'glesha --help' to get started"
    exit
fi

refresh_command=''

tilde_bin_dir=$(tildify "$bin_dir")
quoted_install_dir=\"${install_dir//\"/\\\"}\"

if [[ $quoted_install_dir = \"$HOME/* ]]; then
    quoted_install_dir=${quoted_install_dir/$HOME\//\$HOME/}
fi

echo

case $(basename "$SHELL") in
fish)
    commands=(
        "set --export $install_env $quoted_install_dir"
        "set --export PATH $bin_env \$PATH"
    )

    fish_config=$HOME/.config/fish/config.fish
    tilde_fish_config=$(tildify "$fish_config")

    if [[ -w $fish_config ]]; then
        info "[+] Configuring shell environment for fish"
        {
            echo -e '\n# glesha'

            for command in "${commands[@]}"; do
                echo "$command"
            done
        } >>"$fish_config"

        info "[+] Added \"$tilde_bin_dir\" to \$PATH in \"$tilde_fish_config\""

        refresh_command="source $tilde_fish_config"
    else
        echo "Manually add the directory to $tilde_fish_config (or similar):"

        for command in "${commands[@]}"; do
            info_bold "  $command"
        done
    fi
    ;;
zsh)
    commands=(
        "export $install_env=$quoted_install_dir"
        "export PATH=\"$bin_env:\$PATH\""
    )

    zsh_config=$HOME/.zshrc
    tilde_zsh_config=$(tildify "$zsh_config")

    if [[ -w $zsh_config ]]; then
        info "[+] Configuring shell environment for zsh"
        {
            echo -e '\n# glesha'

            for command in "${commands[@]}"; do
                echo "$command"
            done
        } >>"$zsh_config"

        info "[+] Added \"$tilde_bin_dir\" to \$PATH in \"$tilde_zsh_config\""

        refresh_command="exec $SHELL"
    else
        echo "Manually add the directory to $tilde_zsh_config (or similar):"

        for command in "${commands[@]}"; do
            info_bold "  $command"
        done
    fi
    ;;
bash)
    commands=(
        "export $install_env=$quoted_install_dir"
        "export PATH=\"$bin_env:\$PATH\""
    )

    bash_configs=(
        "$HOME/.bash_profile"
        "$HOME/.bashrc"
    )

    if [[ ${XDG_CONFIG_HOME:-} ]]; then
        bash_configs+=(
            "$XDG_CONFIG_HOME/.bash_profile"
            "$XDG_CONFIG_HOME/.bashrc"
            "$XDG_CONFIG_HOME/bash_profile"
            "$XDG_CONFIG_HOME/bashrc"
        )
    fi

    set_manually=true
    for bash_config in "${bash_configs[@]}"; do
        tilde_bash_config=$(tildify "$bash_config")

        if [[ -w $bash_config ]]; then
            info "[+] Configuring shell environment for bash"
            {
                echo -e '\n# glesha'

                for command in "${commands[@]}"; do
                    echo "$command"
                done
            } >>"$bash_config"

            info "[+] Added \"$tilde_bin_dir\" to \$PATH in \"$tilde_bash_config\""

            refresh_command="source $bash_config"
            set_manually=false
            break
        fi
    done

    if [[ $set_manually = true ]]; then
        echo "Manually add the directory to $tilde_bash_config (or similar):"

        for command in "${commands[@]}"; do
            info_bold "  export $install_env=$quoted_install_dir"
            info_bold "  export PATH=\"$bin_env:\$PATH\""
        done
    fi
    ;;
*)
    echo 'Manually add the directory to ~/.bashrc (or similar):'
    info_bold "  export $install_env=$quoted_install_dir"
    info_bold "  export PATH=\"$bin_env:\$PATH\""
    ;;
esac

echo
info "To get started, run:"
echo

if [[ $refresh_command ]]; then
    info_bold "  $refresh_command"
fi

info_bold "  glesha --help"
