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

# K8Studio Azure AKS kubelogin lab
#
# This script creates or configures a small AKS cluster that authenticates
# through Microsoft Entra ID, Azure CLI, and kubelogin exec auth.
#
# Requirements:
# - Azure CLI
# - kubelogin
# - kubectl
# - An Azure subscription
#
# Usage:
#   ./k8studio-aks-kubelogin-lab.sh login
#   ./k8studio-aks-kubelogin-lab.sh create
#   ./k8studio-aks-kubelogin-lab.sh kubeconfig
#   ./k8studio-aks-kubelogin-lab.sh verify
#   ./k8studio-aks-kubelogin-lab.sh destroy

RESOURCE_GROUP="${RESOURCE_GROUP:-k8studio-auth-aks-rg}"
CLUSTER_NAME="${CLUSTER_NAME:-k8studio-auth-aks}"
LOCATION="${LOCATION:-eastus}"
NODE_VM_SIZE="${NODE_VM_SIZE:-Standard_D2s_v7}"
NODE_COUNT="${NODE_COUNT:-1}"
KUBECONFIG_PATH="${KUBECONFIG_PATH:-${HOME}/.kube/k8studio-auth-aks.yaml}"
AKS_ROLE="${AKS_ROLE:-Azure Kubernetes Service RBAC Cluster Admin}"

usage() {
  cat <<USAGE
K8Studio Azure AKS kubelogin lab

Commands:
  login        Run Azure browser login
  create       Create a small Entra-backed AKS cluster and grant AKS RBAC
  kubeconfig   Generate and convert the AKS kubeconfig with kubelogin
  verify       Verify kubectl can reach the cluster through kubelogin
  destroy      Delete the resource group to stop charges

Environment:
  RESOURCE_GROUP=${RESOURCE_GROUP}
  CLUSTER_NAME=${CLUSTER_NAME}
  LOCATION=${LOCATION}
  NODE_VM_SIZE=${NODE_VM_SIZE}
  NODE_COUNT=${NODE_COUNT}
  KUBECONFIG_PATH=${KUBECONFIG_PATH}
  AKS_ROLE=${AKS_ROLE}

Example:
  ./k8studio-aks-kubelogin-lab.sh login
  ./k8studio-aks-kubelogin-lab.sh create
  ./k8studio-aks-kubelogin-lab.sh kubeconfig
  ./k8studio-aks-kubelogin-lab.sh verify
  ./k8studio-aks-kubelogin-lab.sh destroy
USAGE
}

require_command() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "Missing required command: $1" >&2
    exit 1
  fi
}

login() {
  require_command az
  az login
  az account show --output table
}

create_cluster() {
  require_command az

  az group create \
    --name "${RESOURCE_GROUP}" \
    --location "${LOCATION}" \
    --tags Owner=K8Studio Project=auth-lab AutoDelete=true

  az aks create \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --node-count "${NODE_COUNT}" \
    --node-vm-size "${NODE_VM_SIZE}" \
    --enable-aad \
    --enable-azure-rbac \
    --tier free \
    --generate-ssh-keys \
    --tags Owner=K8Studio Project=auth-lab AutoDelete=true

  local aks_id user_id
  aks_id="$(az aks show --resource-group "${RESOURCE_GROUP}" --name "${CLUSTER_NAME}" --query id --output tsv)"
  user_id="$(az ad signed-in-user show --query id --output tsv)"

  az role assignment create \
    --assignee-object-id "${user_id}" \
    --assignee-principal-type User \
    --role "${AKS_ROLE}" \
    --scope "${aks_id}" || true
}

write_kubeconfig() {
  require_command az
  require_command kubelogin

  mkdir -p "$(dirname "${KUBECONFIG_PATH}")"

  az aks get-credentials \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --file "${KUBECONFIG_PATH}" \
    --overwrite-existing

  kubelogin convert-kubeconfig \
    -l azurecli \
    --kubeconfig "${KUBECONFIG_PATH}"

  echo "Wrote kubeconfig:"
  echo "${KUBECONFIG_PATH}"
}

verify() {
  require_command kubectl
  KUBECONFIG="${KUBECONFIG_PATH}" kubectl get nodes
  KUBECONFIG="${KUBECONFIG_PATH}" kubectl auth can-i get pods --all-namespaces
}

destroy() {
  require_command az
  az group delete --name "${RESOURCE_GROUP}" --yes
}

case "${1:-}" in
  login)
    login
    ;;
  create)
    create_cluster
    ;;
  kubeconfig)
    write_kubeconfig
    ;;
  verify)
    verify
    ;;
  destroy)
    destroy
    ;;
  -h|--help|help|"")
    usage
    ;;
  *)
    echo "Unknown command: $1" >&2
    usage
    exit 1
    ;;
esac
