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

CTX="${CTX:?CTX is required}"
RELEASE_NAME="${RELEASE_NAME:-victoria-metrics-operator}"
RELEASE_NAMESPACE="${RELEASE_NAMESPACE:-observability}"
OPERATOR_NAMESPACE="${OPERATOR_NAMESPACE:-monitoring-serverless}"
DRY_RUN="true"

usage() {
  cat <<'EOF'
Usage: helm-patch.sh [--execute]

Options:
  --execute   apply changes for real
EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --execute)
      DRY_RUN="false"
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "unknown argument: $1" >&2
      usage >&2
      exit 1
      ;;
  esac
done

k() {
  kubectl --context "$CTX" "$@"
}

PATCH="$(cat <<EOF
{"metadata":{"labels":{"app.kubernetes.io/managed-by":"Helm"},"annotations":{"meta.helm.sh/release-name":"$RELEASE_NAME","meta.helm.sh/release-namespace":"$RELEASE_NAMESPACE"}}}
EOF
)"

run_patch() {
  if [[ "$DRY_RUN" == "true" ]]; then
    echo "+ kubectl --context $CTX $* --dry-run=client"
    k "$@" --dry-run=client
  else
    echo "+ kubectl --context $CTX $*"
    k "$@"
  fi
}

patch_if_exists() {
  local ref="$1"
  if ! k get "$ref" >/dev/null 2>&1; then
    echo "skip $ref"
    return 0
  fi
  echo "patch $ref"
  run_patch patch "$ref" --type merge -p "$PATCH"
}

patch_if_exists_ns() {
  local ns="$1"
  local ref="$2"
  if ! k -n "$ns" get "$ref" >/dev/null 2>&1; then
    echo "skip $ns/$ref"
    return 0
  fi
  echo "patch $ns/$ref"
  run_patch -n "$ns" patch "$ref" --type merge -p "$PATCH"
}

echo "Updating CRD metadata..."
while IFS= read -r ref; do
  [[ -n "$ref" ]] || continue
  patch_if_exists "$ref"
done < <(k get crd -o name | grep 'victoriametrics.com' || true)

echo "Updating cluster-scoped RBAC..."
while IFS= read -r ref; do
  [[ -n "$ref" ]] || continue
  patch_if_exists "$ref"
done < <(k get clusterrole -o name | grep -E 'victoria|o11y-vector|vector-operator' || true)

while IFS= read -r ref; do
  [[ -n "$ref" ]] || continue
  patch_if_exists "$ref"
done < <(k get clusterrolebinding -o name | grep -E 'victoria|o11y-vector|vector-operator' || true)
