#!/bin/bash

ynh_go_try_bash_extension() {
  if [ -x src/configure ]; then
    src/configure && make -C src || {
      ynh_print_info "Optional bash extension failed to build, but things will still work normally."
    }
  fi
}

readonly GOENV_INSTALL_DIR="/opt/goenv"
# goenv_ROOT is the directory of goenv, it needs to be loaded as a environment variable.
export GOENV_ROOT="$GOENV_INSTALL_DIR"

_ynh_load_go_in_path_and_other_tweaks() {

    # Get the absolute path of this version of go
    go_dir="$GOENV_INSTALL_DIR/versions/$app/bin"

    # Load the path of this version of go in $PATH
    if [[ :$PATH: != *":$go_dir"* ]]; then
        PATH="$go_dir:$PATH"
    fi

    # Export PATH such that it's available through sudo -E / ynh_exec_as $app
    export PATH

    # This is in full lowercase such that it gets replaced in templates
    path_with_go="$PATH"
    PATH_with_go="$PATH"

    # Sets the local application-specific go version
    pushd ${install_dir}
        $GOENV_INSTALL_DIR/bin/goenv local $go_version
    popd
}

# Install a specific version of Go using goenv
#
# The installed version is defined by $nodejs_version which should be defined as global prior to calling this helper
#
# This helper creates a /etc/profile.d/goenv.sh that configures PATH environment for goenv
# for every LOGIN user, hence your user must have a defined shell (as opposed to /usr/sbin/nologin)
#
# Don't forget to execute go-dependent command in a login environment
# (e.g. sudo --login option)
# When not possible (e.g. in systemd service definition), please use direct path
# to goenv shims (e.g. $goenv_ROOT/shims/bundle)
#
# usage: ynh_go_install
#
# Requires YunoHost version 3.2.2 or higher.
ynh_go_install () {

    [[ -n "${go_version:-}" ]] || ynh_die "\$go_version should be defined prior to calling ynh_go_install"

    # Load goenv path in PATH
    local CLEAR_PATH="$GOENV_INSTALL_DIR/bin:$PATH"

    # Remove /usr/local/bin in PATH in case of Go prior installation
    PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')

    # Move an existing Go binary, to avoid to block goenv
    test -x /usr/bin/go && mv /usr/bin/go /usr/bin/go_goenv

    # Install or update goenv
    mkdir -p $GOENV_INSTALL_DIR
    pushd "$GOENV_INSTALL_DIR"
        if ! [ -x "$GOENV_INSTALL_DIR/bin/goenv" ]; then
            ynh_print_info "Downloading goenv..."
            git init -q
            git remote add origin https://github.com/syndbg/goenv.git 
        else
            ynh_print_info "Updating goenv..."
        fi
        git fetch -q --tags --prune origin
        local git_latest_tag=$(git describe --tags "$(git rev-list --tags --max-count=1)")
        git checkout -q "$git_latest_tag"
        ynh_go_try_bash_extension
        goenv=$GOENV_INSTALL_DIR/bin/goenv
    popd

    # Install or update xxenv-latest
    mkdir -p "$GOENV_INSTALL_DIR/plugins/xxenv-latest"
    pushd "$GOENV_INSTALL_DIR/plugins/xxenv-latest"
        if ! [ -x "$GOENV_INSTALL_DIR/plugins/xxenv-latest/bin/goenv-latest" ]; then
            ynh_print_info "Downloading xxenv-latest..."
            git init -q
            git remote add origin https://github.com/momo-lab/xxenv-latest.git 
        else
            ynh_print_info "Updating xxenv-latest..."
        fi
        git fetch -q --tags --prune origin
        local git_latest_tag=$(git describe --tags "$(git rev-list --tags --max-count=1)")
        git checkout -q "$git_latest_tag"
    popd

    # Enable caching
    mkdir -p "${GOENV_INSTALL_DIR}/cache"

    # Create shims directory if needed
    mkdir -p "${GOENV_INSTALL_DIR}/shims"

    # Restore /usr/local/bin in PATH
    PATH=$CLEAR_PATH

    # And replace the old Go binary
    test -x /usr/bin/go_goenv && mv /usr/bin/go_goenv /usr/bin/go

    # Install the requested version of Go
    local final_go_version=$("$goenv_latest_dir/bin/goenv-latest" --print "$go_version")
    ynh_print_info "Installation of Go-$final_go_version"
    goenv install --quiet --skip-existing "$final_go_version" 2>&1

    # Store go_version into the config of this app
    ynh_app_setting_set --app="$app" --key="go_version" --value="$final_go_version"
    go_version=$final_go_version

    # Cleanup Go versions
    _ynh_go_cleanup

    # Set environment for Go users
    echo  "#goenv
export GOENV_ROOT=$GOENV_INSTALL_DIR
export PATH=\"$GOENV_INSTALL_DIR/bin:$PATH\"
eval \"\$(goenv init -)\"
#goenv" > /etc/profile.d/goenv.sh

    # Load the environment
    eval "$(goenv init -)"

    _ynh_load_go_in_path_and_other_tweaks
}

# Remove the version of Go used by the app.
#
# This helper will also cleanup Go versions
#
# usage: ynh_go_remove
ynh_go_remove () {
    local go_version=$(ynh_app_setting_get --key="go_version")

    # Load goenv path in PATH
    local CLEAR_PATH="$GOENV_INSTALL_DIR/bin:$PATH"

    # Remove /usr/local/bin in PATH in case of Go prior installation
    PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')

    # Remove the line for this app
    ynh_app_setting_delete --key="go_version"

    # Cleanup Go versions
    _ynh_go_cleanup
}

# Remove no more needed versions of Go used by the app.
#
# This helper will check what Go version are no more required,
# and uninstall them
# If no app uses Go, goenv will be also removed.
#
# usage: _ynh_go_cleanup
_ynh_go_cleanup () {

    # List required Go versions
    local installed_apps=$(yunohost app list --output-as json --quiet | jq -r .apps[].id)
    local required_go_versions=""
    for installed_app in $installed_apps
    do
        local installed_app_go_version=$(ynh_app_setting_get --app=$installed_app --key="go_version")
        if [[ $installed_app_go_version ]]
        then
            required_go_versions="${installed_app_go_version}\n${required_go_versions}"
        fi
    done

    # Remove no more needed Go versions
    local installed_go_versions=$(goenv versions --bare --skip-aliases | grep -Ev '/')
    for installed_go_version in $installed_go_versions
    do
        if ! `echo ${required_go_versions} | grep "${installed_go_version}" 1>/dev/null 2>&1`
        then
            ynh_print_info "Removing of Go-$installed_go_version"
            $GOENV_INSTALL_DIR/bin/goenv uninstall --force "$installed_go_version"
        fi
    done

    # If none Go version is required
    if [[ ! $required_go_versions ]]
    then
        # Remove goenv environment configuration
        ynh_print_info "Removing of goenv"
        ynh_safe_rm "$GOENV_INSTALL_DIR"
        ynh_safe_rm "/etc/profile.d/goenv.sh"
    fi
}