#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail

ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/../..; pwd -P)

# eks or gke
ENV=${ENV:-"eks"}

case $ENV in
eks)
    VAR_IMG_HUB=ecr
    ;;
gke)
    VAR_IMG_HUB=gcr
    ;;
*)
    echo "Unknown env ${ENV}"
    exit -1
    ;;
esac

WITH_KUBECONFIG=true
source $ROOT/hack/lib/vars.sh
source $ROOT/hack/lib/image.sh
source $ROOT/hack/lib/pulumi/util.sh
source $ROOT/hack/lib/pulumi/e2e/mock.sh
source $ROOT/hack/lib/pulumi/e2e/deploy.sh

# tools
KUBECTL=${KUBECTL:-"kubectl"}
GINKGO=${GINKGO:-"$ROOT/bin/ginkgo"}

FOCUS=${FOCUS:-".*"}
SELECTOR=${SELECTOR:-"For=Core"}

tests::e2e::mock_env() {
    local re_mock=${1:-0}

    mkdir -p ${VAR_CACHE_DIR}
    local mock_file=${VAR_CACHE_DIR}/is_mocked

    if [[ ! -f $mock_file || $re_mock != 0 ]]; then
        echo "Try to mock pulumi stack in local"
        lib::pulumi::e2e::mock::mock_base_stack ${VAR_BASE_KUBECONFIG} ${VAR_BASE_CONTEXT}
        lib::pulumi::e2e::mock::mock_infra_api_stack
        lib::pulumi::e2e::mock::mock_eks_shared_tier_stack ${VAR_EKS_KUBECONFIG} ${VAR_EKS_CONTEXT}
        lib::pulumi::e2e::mock::mock_gke_shared_tier_stack ${VAR_GKE_KUBECONFIG} ${VAR_GKE_CONTEXT}
        touch $mock_file
    fi
}


tests::e2e::e2e() {
    local type=${1:-"local"}
    local env=${2:-"eks"}
    local marker=${3:-""}
    local re_mock_env=${4:-0}
    local re_deploy=${5:-0}

    lib::pulumi::util::login $type

    if [[ $type == "local" ]]; then
        tests::e2e::mock_env ${re_mock_env}
    else
        # always re-deploy manager in cloud
        re_deploy=1
    fi

    mkdir -p ${VAR_CACHE_DIR}
    local last_deploy_commit_file=${VAR_CACHE_DIR}/last_deploy_commit
    local commit=$(git rev-parse --short HEAD)

    if [[ $re_deploy == 0 ]]; then
        if [[ ! -f $last_deploy_commit_file ]]; then
            echo "Manager is not deployed, try to deploy($commit)"

            lib::pulumi::e2e::deploy::install_manager $type $env $marker
            lib::pulumi::e2e::deploy::install_manager $type $env $marker-1

            echo  $commit > $last_deploy_commit_file
        else
            local last_deploy_commit=$(cat $last_deploy_commit_file)
            if [[ $last_deploy_commit != $commit ]]; then
                echo "Manager is updated, try to redeploy($last_deploy_commit -> $commit)"

                lib::pulumi::e2e::deploy::install_manager $type $env $marker
                lib::pulumi::e2e::deploy::install_manager $type $env $marker-1

                echo  $commit > $last_deploy_commit_file
            else
                echo "Skip deploy manager. You can set RE_DEPLOY=1 to force re-deploy manager"
            fi
        fi
    else
        echo "Force redeploy manager($commit)"

        lib::pulumi::e2e::deploy::install_manager $type $env $marker
        lib::pulumi::e2e::deploy::install_manager $type $env $marker-1

        echo  $commit > $last_deploy_commit_file
    fi

    local kubeconfig=${VAR_GKE_KUBECONFIG}
    local kubectx=${VAR_GKE_CONTEXT}

    if [[ $env == "eks" ]]; then
        kubeconfig=${VAR_EKS_KUBECONFIG}
        kubectx=${VAR_EKS_CONTEXT}

        $GINKGO \
            -stream \
            --nodes=4 \
            $ROOT/tests/apie2e \
            -- \
            --kube-config=${VAR_INFRA_API_KUBECONFIG} \
            --kube-context=${VAR_INFRA_API_CONTEXT} \
            --eks-kube-config=${kubeconfig} \
            --eks-kube-context=${kubectx} \
            --kube-label=${env}-${marker} \
            --aws-region=${VAR_AWS_REGION} \
            --namespace=${marker} \
            --ginkgo.focus=${FOCUS} \
            --test.timeout=1h
    fi

    $GINKGO \
        -stream \
        --nodes=4 \
        $ROOT/tests \
        -- \
        --kubeconfig=${kubeconfig} \
        --context=${kubectx} \
        --infra-kubeconfig=${VAR_INFRA_API_KUBECONFIG} \
        --infra-context=${VAR_INFRA_API_CONTEXT} \
        --aws-region=${VAR_AWS_REGION} \
        --gcp-region=${VAR_GCP_REGION} \
        --kube-cluster-name-base=${env}-${marker} \
        --selector="${SELECTOR}" \
        --cloud="${env}" \
        --test.timeout=1h


    if [[ $type == "cloud" ]]; then
        $KUBECTL wait --for delete ns \
            --kubeconfig=${VAR_INFRA_API_KUBECONFIG} \
            --context=${VAR_INFRA_API_CONTEXT} \
            --timeout=5m \
            -l testing.tidbcloud.com/for=e2e,testing.tidbcloud.com/e2e-id=${env}-${marker}
        lib::pulumi::e2e::deploy::uninstall_manager $type $env $marker
        lib::pulumi::e2e::deploy::uninstall_manager $type $env $marker-1
    fi
}

# RANDOM_CLUSTER is identity of an e2e test
# TODO: change to a more meaningful name
RANDOM_CLUSTER=${RANDOM_CLUSTER:-"$(git config user.name)"}
# normally empty, only sometimes used for testing
SUFFIX=${SUFFIX:-""}
RE_MOCK_ENV=${RE_MOCK_ENV:-0}
RE_DEPLOY=${RE_DEPLOY:-0}
# local or cloud
MODE=${MODE:-"local"}

tests::e2e::e2e $MODE $ENV $RANDOM_CLUSTER$SUFFIX $RE_MOCK_ENV $RE_DEPLOY
