#!/bin/bash
list_versions() {
    echo "installed versions:"
    for i in "$HOME"/.go/go1*; do basename "$i"; done
    echo ""
}

install_version() {
    check_valid_patch $1
    if [[ $valid != 'true' ]]; then
        echo "invalid version $1"
        echo "using $(go version)"
        exit 1
    fi

    fname="$HOME/.go/downloads/$1.$goos-$goarch.tar.gz"

    if [[ ! -f $fname ]]; then
        curl -Lo $fname https://dl.google.com/go/$1.$goos-$goarch.tar.gz
    fi
    cd $HOME/.go/downloads
    tar -zxf $1.$goos-$goarch.tar.gz
    mv go/ ../$1
    check_exists $1
    link_version $1

    install_modules
}

link_version() {
    if [[ $exists == 'true' ]]; then
        ln -sfn $HOME/.go/$1 $HOME/.go/go
    fi
}

check_valid_minor() {
    if [[ $1 =~ go1\.[0-9]{1,2} ]]; then
        valid='true'
    fi
}

check_valid_patch() {
    if [[ $1 =~ go1\.[0-9]{1,2}\.[0-9]{1,2} ]]; then
        valid='true'
    fi
}

check_exists() {
    if [[ -d $HOME/.go/$1 ]]; then
        exists='true'
    fi
}

remove_version() {
    check_exists $1
    if [[ $exists == 'true' ]]; then
        if [[ $current_link == $1 ]]; then
            echo "cannot remove version $1 because it is currently in use"
        else
            rm -rf $HOME/.go/$1
            echo "removed version $1"
        fi
    else
        echo "version $1 not installed"
    fi
}

get_latest_patch_for_minor() {
    version=$(curl -s "https://go.dev/dl/?mode=json&include=all" | grep -o "$1.*.linux-amd64.tar.gz" | head -n 1 | tr -d '\r\n' | sed 's/[.]linux-amd64[.]tar[.]gz//')
    if [[ $version == '' ]]; then
        echo "could not determine latest version for $1."
        exit 1
    else
        echo "latest $1 patch: $version"
    fi
}

prompt_install() {
    echo "$1 not found in $HOME/.go"
    list_versions
    check_valid_patch $1

    if [[ $valid == 'true' ]]; then
        echo "attempt to download and install? [y/n]"
        read input
        if [[ $input == 'y' ]]; then
            install_version $1
        fi
    else
        check_valid_minor $1
        if [[ $valid == 'true' ]]; then
            get_latest_patch_for_minor $1
            check_exists $version
            if [[ $exists == 'true' ]]; then
               link_version $version
            else
                prompt_install $version
            fi
        else
            echo "invalid version $1"
            echo "using $(go version)"
            exit 1
        fi
    fi
}

install_modules() {
    fname="$HOME/.config/mygvm/modules_to_install"
    echo "attempting to install nvim required binaries and modules at $fname"
    [[ ! -f $fname ]] && echo "no modules file at $fname" && return

    while IFS= read -r line; do
    if [[ "$line" != "" ]]; then 
        echo "running go install $line"
        go install $line
    fi
    done < "$HOME/.config/mygvm/modules_to_install"

    [[ $(which nvim) ]] && nvim --headless +GoInstallBinaries +q
    echo ""
}

mkdir -p "$HOME/.go/downloads"
current_link=$(basename $(readlink $HOME/.go/go))
uname_m=$(uname -m)
goarch='amd64'
if [[ $uname_m == 'arm64' || $uname_m == 'aarch64' ]]; then
    goarch='arm64'
fi
goos='linux'
if [[ $(uname) == 'Darwin' ]]; then
    goos='darwin'
fi
valid='false'
exists='false'

version=''

check_exists $1
if [[ $1 == '' ]]; then
    list_versions
elif [[ $1 == 'list' ]]; then
    list_versions
elif [[ $1 == 'remove' ]]; then
    remove_version $2
elif [[ $1 == 'uninstall' ]]; then
    remove_version $2
elif [[ $1 == 'install' ]]; then
    install_version $2
elif [[ $1 == 'use' ]]; then
    if [[ $2 == 'local' ]]; then
        go_mod_json=$(go mod edit -json)
        if [[ $? == 1 ]]; then
            echo "unable to find go.mod"
            echo "using $(go version)"
            exit 1
        else
            version_to_use=go$(jq -r .Go <<< $go_mod_json)
        fi
    else
        version_to_use=$2
    fi
    check_exists $version_to_use
    if [[ $exists == true ]]; then
        link_version $version_to_use
    else
        prompt_install $version_to_use
    fi
    install_modules
elif [[ $1 == 'modules' ]]; then
    install_modules
elif [[ $exists == 'true' ]]; then
    link_version $1
else
    prompt_install $1
fi

echo "using $(go version)"

