#!/bin/sh
set -eu

if [ "$#" -ne 4 ]; then
  echo "usage: $0 <kubeconfig> <context> <cluster-name> <region>" >&2
  exit 2
fi

kubeconfig=$1
kube_context=$2
cluster_name=$3
region=$4
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)

[ -n "${CP9_SESSION_CONTEXT:-}" ] && [ -f "$CP9_SESSION_CONTEXT" ] || {
  echo "CP9_SESSION_CONTEXT must name the persisted session context" >&2
  exit 1
}
command -v helm >/dev/null 2>&1 || {
  echo "Starter regional platform requires helm on the selected controller" >&2
  exit 1
}

context_value() {
  python3 - "$CP9_SESSION_CONTEXT" "$1" <<'PY'
import json
import sys

value = json.loads(open(sys.argv[1], encoding="utf-8").read())
for key in sys.argv[2].split("."):
    value = value.get(key, "") if isinstance(value, dict) else ""
print(str(value).strip())
PY
}

owner=$(context_value session_tags.cp9-owner)
session=$(context_value session_tags.cp9-session)
ttl=$(context_value ttl_expires_at)
[ -n "$owner" ] && [ -n "$session" ] && [ -n "$ttl" ] || {
  echo "session context must provide cp9-owner, cp9-session, and ttl_expires_at" >&2
  exit 1
}
if [ "${#session}" -le 23 ]; then
  ingress_lb_name="$session-ingress"
else
  ingress_lb_name="$session-i"
fi

vpc_id=$(aws eks describe-cluster \
  --region "$region" \
  --name "$cluster_name" \
  --query 'cluster.resourcesVpcConfig.vpcId' \
  --output text)
[ -n "$vpc_id" ] && [ "$vpc_id" != "None" ] || {
  echo "cannot resolve Starter EKS VPC ID" >&2
  exit 1
}

helm_root=$(mktemp -d)
trap 'rm -rf "$helm_root"' EXIT
export HELM_REPOSITORY_CACHE="$helm_root/cache"
export HELM_REPOSITORY_CONFIG="$helm_root/repositories.yaml"

helm repo add projectcalico https://docs.tigera.io/calico/charts >/dev/null
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/ >/dev/null
helm repo add eks https://aws.github.io/eks-charts >/dev/null
helm repo add autoscaler https://kubernetes.github.io/autoscaler >/dev/null
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx >/dev/null

helm --kubeconfig "$kubeconfig" --kube-context "$kube_context" upgrade --install \
  tigera-operator projectcalico/tigera-operator \
  --version v3.25.1 \
  --namespace tigera-operator \
  --create-namespace \
  --set installation.kubernetesProvider=EKS \
  --set-string installation.kubeletVolumePluginPath=None \
  --set-string installation.registry=gcr.io/ \
  --set-string installation.imagePath=projectcalico-org \
  --set apiServer.enabled=false \
  --wait \
  --timeout 10m \
  --history-max 3

kubectl --kubeconfig "$kubeconfig" --context "$kube_context" \
  wait --for=create namespace/calico-system --timeout=10m
kubectl --kubeconfig "$kubeconfig" --context "$kube_context" \
  --namespace calico-system rollout status daemonset/calico-node --timeout=10m
kubectl --kubeconfig "$kubeconfig" --context "$kube_context" \
  --namespace calico-system rollout status deployment/calico-kube-controllers --timeout=10m

helm --kubeconfig "$kubeconfig" --kube-context "$kube_context" upgrade --install \
  metrics-server metrics-server/metrics-server \
  --version 3.8.2 \
  --namespace kube-system \
  --set replicas=1 \
  --wait \
  --timeout 10m \
  --history-max 3

kubectl --kubeconfig "$kubeconfig" --context "$kube_context" \
  wait --for=condition=Available apiservice/v1beta1.metrics.k8s.io --timeout=10m

helm --kubeconfig "$kubeconfig" --kube-context "$kube_context" upgrade --install \
  cluster-autoscaler autoscaler/cluster-autoscaler \
  --version 9.46.6 \
  --namespace kube-system \
  --set-string autoDiscovery.clusterName="$cluster_name" \
  --set-string awsRegion="$region" \
  --set rbac.serviceAccount.create=true \
  --set rbac.serviceAccount.name=cluster-autoscaler \
  --set replicaCount=1 \
  --set extraArgs.skip-nodes-with-local-storage=false \
  --set extraArgs.skip-nodes-with-system-pods=false \
  --set extraArgs.balance-similar-node-groups=true \
  --set-string extraArgs.scale-down-utilization-threshold=0.5 \
  --set-string extraArgs.max-node-provision-time=2m \
  --set-string extraArgs.max-total-unready-percentage=100 \
  --set resources.requests.cpu=200m \
  --set resources.requests.memory=500Mi \
  --set resources.limits.cpu=600m \
  --set resources.limits.memory=1500Mi \
  --wait \
  --timeout 10m \
  --history-max 3

kubectl --kubeconfig "$kubeconfig" --context "$kube_context" \
  apply -f "$script_dir/node-problem-detector.yaml"
kubectl --kubeconfig "$kubeconfig" --context "$kube_context" \
  --namespace kube-system rollout status daemonset/node-problem-detector --timeout=10m

helm --kubeconfig "$kubeconfig" --kube-context "$kube_context" upgrade --install \
  aws-load-balancer-controller eks/aws-load-balancer-controller \
  --version 1.8.1 \
  --namespace kube-system \
  --set-string clusterName="$cluster_name" \
  --set-string region="$region" \
  --set-string vpcId="$vpc_id" \
  --set replicaCount=1 \
  --set enableCertManager=false \
  --set enableServiceMutatorWebhook=false \
  --set serviceAccount.create=true \
  --set serviceAccount.name=aws-load-balancer-controller \
  --set-string defaultTags.cp9-owner="$owner" \
  --set-string defaultTags.cp9-session="$session" \
  --set-string defaultTags.cp9-managed=true \
  --set-string defaultTags.cp9-ttl="$ttl" \
  --wait \
  --timeout 10m \
  --history-max 3

helm --kubeconfig "$kubeconfig" --kube-context "$kube_context" upgrade --install \
  ingress-nginx ingress-nginx/ingress-nginx \
  --version 4.12.0 \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.replicaCount=1 \
  --set-string controller.config.use-proxy-protocol=true \
  --set-string controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-name="$ingress_lb_name" \
  --set-string controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-type=external \
  --set-string controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-nlb-target-type=ip \
  --set-string controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-scheme=internet-facing \
  --set-string controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-proxy-protocol='*' \
  --set-string controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-cross-zone-load-balancing-enabled=true \
  --set-string controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-additional-resource-tags="cp9-owner=$owner\\,cp9-session=$session\\,cp9-managed=true\\,cp9-ttl=$ttl" \
  --wait \
  --timeout 10m \
  --history-max 3
