#!/usr/bin/env bash

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

ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/..; pwd -P)
source $ROOT/hack/lib/vars.sh
source $ROOT/hack/lib/image.sh

KUSTOMIZE=${KUSTOMIZE:-"$ROOT/bin/kustomize"}
KUBECTL=${KUBECTL:-"kubectl"}

KUBECONFIG=${KUBECONFIG:-"$HOME/.kube/config"}
INFRA_KUBECONFIG=${INFRA_KUBECONFIG:-"$HOME/.kube/config"}

KUBE_CLUSTER_NAME=${KUBE_CLUSTER_NAME:-"test"}
AWS_ACCOUNT_ID=${AWS_ACCOUNT_ID:-"123456"}
OIDC_PROVIDER_ARN=${OIDC_PROVIDER_ARN:-"arn:aws:iam::123456:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/ABCDEFG"}

has_installed=false
deploy::install_infra_api_crd() {
    if [[ $has_installed == "false" ]]; then
        echo "install infra api crd"
        $KUSTOMIZE build ./deploy/crd/infra | $KUBECTL --kubeconfig ${INFRA_KUBECONFIG} apply -f -
        has_installed=true
    fi
}

deploy::install_tidb_operator_crd() {
    echo "install tidb operator crd"
    # TODO: avoid to visit network
    # TODO: change to use specified version
	$KUBECTL --kubeconfig ${KUBECONFIG} apply -f https://raw.githubusercontent.com/pingcap/tidb-operator/master/manifests/crd.yaml
}

deploy::install_crossplane_crd() {
    echo "install crossplane crd"
    # TODO: avoid to visit network
    # TODO: change to use specified version
	$KUBECTL --kubeconfig ${KUBECONFIG} apply -f https://raw.githubusercontent.com/tidbcloud/provider-aws/pingcap/provider-aws/package/crds/route53.aws.crossplane.io_resourcerecordsets.yaml
}

deploy::install_cert_crd() {
  echo "install cert crd"
  $KUBECTL --kubeconfig ${KUBECONFIG} apply -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.crds.yaml
}

deploy::install_ebs_sc() {
    echo "install storageclass ebs-sc"
  	$KUBECTL --kubeconfig ${KUBECONFIG} apply -f ./deploy/samples/ebs-sc.yaml
}

deploy::install_manager() {
    echo "install manager"

    lib::image::get_image_vars manager

    local deployPath=${VAR_CACHE_DIR}/manager/deploy
    mkdir -p ${deployPath}
    # TODO: patches should be removed
    cat <<EOF > ${deployPath}/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: shared-provider-manager
namePrefix: shared-provider-

resources:
- ../../../deploy/components/manager

images:
- name: controller
  newName: ${IMG_REGISTRY}/${IMG_REPO}
  newTag: ${IMG_VERSION}

patches:
# set cluster name
- target:
    kind: Deployment
    name: manager
  patch: |-
    - op: add
      path: /spec/template/spec/containers/0/args/-
      value: --kube-cluster-name=${KUBE_CLUSTER_NAME}
    - op: add
      path: /spec/template/spec/containers/0/args/-
      value: --aws-account-id=${AWS_ACCOUNT_ID}
    - op: add
      path: /spec/template/spec/containers/0/args/-
      value: --oidc-provider-arn=${OIDC_PROVIDER_ARN}
EOF

    $KUSTOMIZE build ${deployPath} | $KUBECTL --kubeconfig ${KUBECONFIG} apply -f -
}

deploy::uninstall_manager() {
    echo "uninstall manager"

    local deployPath=${VAR_CACHE_DIR}/manager/deploy
    $KUSTOMIZE build ${deployPath} | $KUBECTL --kubeconfig ${KUBECONFIG} delete -f -
}

deploy::install_dispatcher() {
    echo "install dispatcher"

    lib::image::get_image_vars dispatcher

    local deployPath=${VAR_CACHE_DIR}/dispatcher/deploy
    mkdir -p ${deployPath}
    # TODO: patches should be removed
    cat <<EOF > ${deployPath}/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: shared-provider-dispatcher
namePrefix: shared-provider-

resources:
- ../../../deploy/components/dispatcher

images:
- name: dispatcher
  newName: ${IMG_REGISTRY}/${IMG_REPO}
  newTag: ${IMG_VERSION}
EOF

    $KUSTOMIZE build ${deployPath} | $KUBECTL --kubeconfig ${KUBECONFIG} apply -f -
}

deploy::uninstall_dispatcher() {
    echo "uninstall dispatcher"
    local deployPath=${VAR_CACHE_DIR}/dispatcher/deploy
    $KUSTOMIZE build ${deployPath} | $KUBECTL --kubeconfig ${INFRA_KUBECONFIG} delete -f -
}

deploy::wait_manager() {
    echo "wait for manager"
    $KUBECTL --kubeconfig ${KUBECONFIG} \
        wait deployment/shared-provider-manager \
        --for=condition=available \
        -n shared-provider-manager \
        --timeout=2m
}

deploy::wait_dispatcher() {
    echo "wait for dispatcher"
    $KUBECTL --kubeconfig ${INFRA_KUBECONFIG} \
        wait deployment/shared-provider-dispatcher \
        --for=condition=available \
        -n shared-provider-dispatcher \
        --timeout=2m
}


ACTION=${1:-"install"}
TARGETS=${@:2}

for TARGET in ${TARGETS}; do
    case ${TARGET} in
    manager)
        case ${ACTION} in
        install)
            deploy::install_infra_api_crd
            deploy::install_tidb_operator_crd
            deploy::install_crossplane_crd
            deploy::install_cert_crd
            # deploy::install_ebs_sc
            deploy::install_manager
            ;;
        uninstall)
            # TODO: clean crd
            deploy::uninstall_manager
            ;;
        *)
            echo "`basename ${0}`:usage: [ACTION] [TARGETS]"
            echo "invalid action $ACTION"
            exit 1
            ;;
        esac
        ;;
    dispatcher)
        case ${ACTION} in
        install)
            deploy::install_infra_api_crd
            deploy::install_dispatcher
            ;;
        uninstall)
            # TODO: clean crd
            deploy::uninstall_dispatcher
            ;;
        *)
            echo "`basename ${0}`:usage: [ACTION] [TARGETS]"
            echo "invalid action $ACTION"
            exit 1
            ;;
        esac
        ;;
    *)
        echo "`basename ${0}`:usage: [ACTION] [TARGETS]"
        echo "invalid target $TARGET"
        exit 1
        ;;
    esac
done

for TARGET in ${TARGETS}; do
    case $TARGET in
    manager)
        deploy::wait_manager
        ;;
    dispatcher)
        deploy::wait_dispatcher
        ;;
    esac
done
