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

function usage() {
    cat <<EOF
Usage:
    cluster.sh
        up [image-name]   Create a Kind cluster and deploy a TiDB cluster with the given cluster proxy image.
        down              Destory the created cluster.

        deploy [image-name]        push images and run pulumi up
        pulumi-up                  run pulumi up
        push-image [image-name]    push image

EOF
    echo "${1:-""}"
    exit 1
}

KIND_LOAD=(kind load)
if [[ -n ${SUDO_DOCKER:-""} ]] ; then
  KIND_LOAD=(sudo "$(which kind)" load)
fi

pingcap_tag='v5.3.0-pre'
pingcap_docker_pd_tag="$pingcap_tag"
pingcap_docker_tidb_tag="$pingcap_tag"
pingcap_docker_tikv_tag="$pingcap_tag"

# Copied from https://kind.sigs.k8s.io/docs/user/local-registry/
function kind-init() {
    # Create a cluster with the local registry enabled in containerd
    cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
    push_pingcap_images
}

function push_pingcap_images() {
    docker pull "pingcap/pd:$pingcap_docker_pd_tag"
    docker pull "pingcap/tidb:$pingcap_docker_tidb_tag"
    docker pull "pingcap/tikv:$pingcap_docker_tikv_tag"
    "${KIND_LOAD[@]}" docker-image "pingcap/pd:$pingcap_docker_pd_tag"
    "${KIND_LOAD[@]}" docker-image "pingcap/tidb:$pingcap_docker_tidb_tag"
    "${KIND_LOAD[@]}" docker-image "pingcap/tikv:$pingcap_docker_tikv_tag"
}


function push_image() {
    image_name=${1:-""}
    if [[ -z "$image_name" ]]; then
        usage "image name required"
    fi

    #    docker pull imega/mysql-client
    #    "${KIND_LOAD[@]}" docker-image imega/mysql-client

    # Tag and push the proxy image to the local registry
    "${KIND_LOAD[@]}" docker-image "$image_name"
}

function cleanup_kind() {
    kind delete cluster --name kind
}

export PULUMI_CONFIG_PASSPHRASE=""
pulumi_config_dir="./specs/pulumi"
function cluster_up() {
    trap '[[ $? -eq 1 ]] && cleanup_kind' EXIT
    
    kind-init
}
    
function pulumi_deploy() {
    pulumi_up "$1" --target urn:pulumi:test::proxy::kubernetes:apps/v1:Deployment::proxy-deployment
    popd >/dev/null
}

function pulumi_all() {
    pulumi_up "$@"
    popd >/dev/null
}

function pulumi_setup() {
    pulumi login --local
    pushd "$pulumi_config_dir"
    version=$(git rev-list HEAD package.json)
    version_file="node_modules/install-version"
    if git diff --quiet package.json && \
        test -f $version_file && [[ $version == $(cat $version_file) ]] ; then
        echo "skip npm install"
    else
        npm install
        echo "$version" > "$version_file"
    fi
}

function pulumi_up() {
    pulumi_setup
    stack_ls=$(pulumi stack ls)
    if ! echo "$stack_ls" | grep -q test  ; then
      pulumi stack init test
      cp Pulumi.local-example.yaml Pulumi.test.yaml
    fi
    if [[ "$(echo "$stack_ls" | grep '\*' | cut -d '*' -f 1)" != test ]] ; then
      pulumi stack select test
    fi
    if [[ -n "${1:-""}" ]] ; then
        pulumi config set proxy:image "$1"
        shift
    fi
    pulumi up -r -f -y "$@"
}



cd "$(dirname "$0")/.."

function arg_or_make_image() {
    if [[ -z "$1" ]] ; then
        ./scripts/make-image.sh
    else
        echo "$1"
    fi
}

case $1 in
    pulumi-up)
        image=$(arg_or_make_image "${2:-""}")
        push_image "$image"
        pulumi_all
    ;;

    push-pingcap-images)
        push_pingcap_images
    ;;

    push-image)
        image=$(arg_or_make_image "${2:-""}")
        push_image "$image"
    ;;

    deploy)
        image=$(arg_or_make_image "${2:-""}")
        push_image "$image"
        pulumi_deploy "$image"
    ;;

    up)
        cluster_up
        image=$(arg_or_make_image "${2:-""}")
        push_image "$image"
        pulumi_all "$image"
    ;;
    
    pulumi-down)
        pulumi_setup
        pulumi destroy -y -f
    ;;

    down)
        pulumi_setup
        pulumi destroy -y -f
        pulumi stack rm -y
        cleanup_kind
    ;;

    *)
        usage "argument needed"
    ;;
esac
