#!/usr/bin/env bash

if [[ -z "${ROOT:-}" ]]; then
    echo "error: ROOT should be initialized"
    exit 1
fi

# load other shell functions
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"

OS=$(go env GOOS)
ARCH=$(go env GOARCH)
OUTPUT=${ROOT}/output
OUTPUT_BIN=${OUTPUT}/bin
DEFAULT_KUBECONFIG=${OUTPUT}/kubeconfig

KUBECTL_VERSION=${KUBECTL_VERSION:-1.14.2}
KUBECTL_BIN="${OUTPUT_BIN}/kubectl-${KUBECTL_VERSION}"
KUBEADM_BIN=${OUTPUT_BIN}/kubeadm
TERRAFORM_VERSION=${TERRAFORM_VERSION:-0.12.19}
TERRAFORM_BIN="${OUTPUT_BIN}/terraform-${TERRAFORM_VERSION}"
# Don't ugprade to 2.15.x/2.16.x until this issue
# (https://github.com/helm/helm/issues/6361) has been fixed.
HELM_VERSION=${HELM_VERSION:-2.11.0}
HELM_BIN="${OUTPUT_BIN}/helm-$HELM_VERSION"
GOMPLATE_VERSION=${GOMPLATE_VERSION:-"3.6.0"}
GOMPLATE_BIN="${OUTPUT_BIN}/gomplate-${GOMPLATE_VERSION}"
PULUMI_VERSION="${PULUMI_VERSION:-1.14.0}"
PULUMI_BIN="${OUTPUT_BIN}/pulumi-${PULUMI_VERSION}"

test -d "$OUTPUT_BIN" || mkdir -p "$OUTPUT_BIN"

aws_exec=( exec )
AWS_RUN=( aws )
AWS_RUN_NO_SESSION=( aws )
TERRAFORM_RUN=( "$TERRAFORM_BIN" )
export TERRAFORM_RUN_NO_AWS=( "${TERRAFORM_RUN[@]}" )
if [[ -z ${AWS_VAULT+undefined-guard} ]] && command -v aws-vault >/dev/null && aws-vault list | grep pingcap >/dev/null ; then
    # Note: some things have an issue with a temporary session token
    # That will need --no-session
    aws_exec=( aws-vault exec pingcap )
    export AWS_RUN=( "${aws_exec[@]}" -- aws )
    export AWS_RUN_NO_SESSION=( "${aws_exec[@]}" --no-session -- aws )
    # Terraform needs --no-session
    # I believe this is because in the current setup it cannot refresh the security token
    # shellcheck disable=SC2034
    export TERRAFORM_RUN=( "${aws_exec[@]}" --no-session -- "$TERRAFORM_BIN" )
fi

function lib::verify_kubeadm() {
    if test -x "$KUBEADM_BIN"; then
        [[ "$($KUBEADM_BIN version -o short | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+')" == "$KUBECTL_VERSION" ]]
        return
    fi
    return 1
}

function lib::verify_terraform() {
    if test -x "$TERRAFORM_BIN"; then
        [[ "$($TERRAFORM_BIN version | head -1 | awk '{print $2}' | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+')" == "$TERRAFORM_VERSION" ]]
        return
    fi
    return 1
}

function lib::ensure_terraform() {
    lib::ensure_tool "$TERRAFORM_BIN" "$TERRAFORM_VERSION" \
        "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_SUBOS_SUBARCH.zip" \
        "unzip" "-c" "-p"
}

function lib::ensure_tool() {
    exe="$1"
    shift
    if test -x "$exe"; then
        return 0
    fi
    version="$1"
    shift
    download_url_template="$1"
    shift
    common::info "Installing $exe $version"
    tmpfile=$(mktemp)
    # shellcheck disable=SC2064
    trap "test -f $tmpfile && rm $tmpfile" RETURN
    download_url="$(echo "$download_url_template" | sed "s|SUBOS|$OS|" | sed "s|SUBARCH|$ARCH|")"
    curl -L -o "$tmpfile" "$download_url"
    "$@" "$tmpfile" > "$exe"
    chmod +x "$exe"
}

function lib::ensure_kubectl() {
    if test -x "$KUBECTL_BIN" ; then
        common::info "kubectl version v${KUBECTL_VERSION} already installed"
        return 0
    fi
    common::info "Installing kubectl v$KUBECTL_VERSION..."
    tmpfile=$(mktemp)
    trap 'test -f $tmpfile && rm $tmpfile' RETURN
    curl -L -o "$tmpfile" "https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/${OS}/${ARCH}/kubectl"
    mv "$tmpfile" "$KUBECTL_BIN"
    chmod +x "$KUBECTL_BIN"
}

function lib::ensure_gomplate() {
    if test -x "$GOMPLATE_BIN" ; then
        common::info "gomplate version v${GOMPLATE_VERSION} already installed"
        return 0
    fi
    common::info "Installing gomplate v${GOMPLATE_VERSION}..."
    tmpfile=$(mktemp)
    trap 'test -f $tmpfile && rm $tmpfile' RETURN
    curl -L -o "$tmpfile" "https://github.com/hairyhenderson/gomplate/releases/download/v${GOMPLATE_VERSION}/gomplate_${OS}-${ARCH}"
    mv "$tmpfile" "$GOMPLATE_BIN"
    chmod +x "$GOMPLATE_BIN"
}

function lib::ensure_kubeadm() {
    if lib::verify_kubeadm; then
        common::info "kubeadm version v${KUBECTL_VERSION} already installed"
        return 0
    fi
    common::info "Installing kubeadm v$KUBECTL_VERSION..."
    tmpfile=$(mktemp)
    trap "test -f $tmpfile && rm $tmpfile" RETURN
    curl -L -o $tmpfile https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/${OS}/${ARCH}/kubeadm
    mv $tmpfile $KUBEADM_BIN
    chmod +x $KUBEADM_BIN
}

function lib::ensure_helm() {
    if test -x "$HELM_BIN" ; then
        return 0
    fi
    common::info "Installing helm v$HELM_VERSION..."
    local HELM_URL=http://storage.googleapis.com/kubernetes-helm/helm-v${HELM_VERSION}-${OS}-${ARCH}.tar.gz
    curl -sL "$HELM_URL" | tar --strip-components 1 -C $OUTPUT_BIN -zxf - ${OS}-${ARCH}/helm
    mv "$OUTPUT_BIN/helm" "$HELM_BIN"
}

function lib::ensure_pulumi() {
    if test -x "$PULUMI_BIN" ; then
        return 0
    fi
    common::info "Installing pulumi v$PULUMI_VERSION..."
    local PULUMI_URL=https://get.pulumi.com/releases/sdk/pulumi-v${PULUMI_VERSION}-${OS}-x64.tar.gz
    curl -L "$PULUMI_URL" | tar -C $OUTPUT_BIN -xz pulumi/pulumi
    mv "$OUTPUT_BIN/pulumi/pulumi" "$PULUMI_BIN"
    rm -r "$OUTPUT_BIN"/pulumi


}
function lib::export_kube_config() {
    local kubecfg=${KUBECONFIG:-$DEFAULT_KUBECONFIG}
    common::info "use kubeconfig: ${kubecfg}"
    export KUBECONFIG="${kubecfg}"
}

[[ ! -z ${ENABLE_DEBUG:-} ]] && set -x || true
