#!/usr/bin/env bash

set -euo pipefail

print_help() {
  cat <<EOF
Configures an ObservabilityPipeline CR by managing telemetry data storage and/or
export settings independently or together.

Usage: $0 [OPTIONS]

Target namespace (required):
  --controlplane-namespace NS  Kubernetes namespace used for the CDP Private Cloud deployment.
                               Resources will be managed in "\${NS}-obs".

Kubernetes connection options (optional, defaults to current kubeconfig):
  --kubeconfig PATH            Path to kubeconfig file (default: \$KUBECONFIG or ~/.kube/config)
  --context CONTEXT            Kubernetes context to use
  --pipeline-name NAME         Name of the ObservabilityPipeline CR (default: observability-pipeline)

Pipeline control (optional, can be used standalone):
  --pipeline-enable            Enable the ObservabilityPipeline.
  --pipeline-disable           Disable the ObservabilityPipeline.
                               When used alone, no credentials or config file are required.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TELEMETRY DATA STORAGE CONFIGURATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Remote access (choose automatic or explicit setup):
  --storage-region REGION      Cloud region (us, eu, ap)
  --storage-account-id UUID            Cloudera Altus account ID

  OR:
  --storage-metrics-ingestion-url URL  Metrics ingestion endpoint
  --storage-dbus-api-url URL               Logs ingestion API endpoint

Credentials (required for metric storage setup; choose inline or file):
  --storage-access-key-id ID           CDP access key ID
  --storage-private-key KEY            CDP private key

  OR:
  --storage-credentials-file PATH      File with credentials:
                                         cdp_access_key_id=...
                                         cdp_private_key=...

DCGM Exporter options (can be used independently of full metric storage setup):
  --dcgm-exporter-enable               Enable DCGM Exporter
  --dcgm-exporter-disable              Disable DCGM Exporter
  --dcgm-exporter-node-selector KEY=VALUE  Node selector for DCGM Exporter pods
  --dcgm-exporter-enable-privileged BOOL   Run with privileged security context (true/false)
  --dcgm-exporter-enable-scc BOOL          Enable SecurityContextConstraints (true/false)
  --dcgm-exporter-runtime-class STRING     Runtime class for DCGM Exporter pods

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TELEMETRY DATA EXPORT CONFIGURATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  --export-patch FILE       Apply telemetry export configuration from a YAML patch file
                               (merge-patched onto spec.telemetryExport of the CR).
                               The file must contain 'spec.telemetryExport' at the top level, e.g.:
                                 spec:
                                   telemetryExport:
                                     enabled: true
                                     metrics:
                                       exporters: [...]
  --export-enable           Enable telemetry export on an already-configured pipeline.
  --export-disable          Disable telemetry export without removing the configuration.
  --export-clear            Remove the telemetry export configuration from the CR entirely.
  --export-show             Print the current spec.telemetryExport configuration and exit.

Validation (applies when --export-patch is used):
  --skip-validation            Skip post-apply collector pod health check.
  --validation-timeout SECS    Seconds to wait for collector pods to stabilise (default: 120).

Other:
  --help                       Show this help message and exit

Notes:
  - Metric storage and telemetry export are independent features and can be configured together.
  - The global spec.enabled flag on the CR is automatically managed:
      • Set to true  whenever any feature is enabled.
      • Set to false when a feature is disabled and no other feature remains enabled.

Examples:
  # Configure metric storage:
  $0 --controlplane-namespace cdp --storage-region us --storage-account-id <UUID> \\
     --storage-credentials-file ~/.cdp/credentials

  # Apply a telemetry export configuration:
  $0 --controlplane-namespace cdp --export-patch my-export.yaml

  # Configure both at once:
  $0 --controlplane-namespace cdp --storage-region us --storage-account-id <UUID> \\
     --storage-credentials-file ~/.cdp/credentials --export-patch my-export.yaml

  # Disable telemetry export:
  $0 --controlplane-namespace cdp --export-disable

  # Enable/disable the entire pipeline:
  $0 --controlplane-namespace cdp --pipeline-disable
  $0 --controlplane-namespace cdp --pipeline-enable

EOF
}

# ---------------------------------------------------------------------------
# Defaults
# ---------------------------------------------------------------------------
# Kubernetes connection
KUBECONFIG_PATH="${KUBECONFIG:-$HOME/.kube/config}"
KUBE_CONTEXT=""
CONTROLPLANE_NAMESPACE=""
KUBE_NAMESPACE=""
PIPELINE_NAME="observability-pipeline"

# Pipeline-level control
PIPELINE_ENABLE=""

# Metric storage
STORAGE_REGION=""
STORAGE_ACCOUNT_ID=""
STORAGE_METRICS_INGESTION_URL=""
STORAGE_DBUS_API_URL=""
STORAGE_ACCESS_KEY_ID=""
STORAGE_PRIVATE_KEY=""
STORAGE_CREDENTIALS_FILE=""

# DCGM Exporter
DCGM_EXPORTER_ENABLE=""
DCGM_EXPORTER_NODE_SELECTOR=""        # KEY=VALUE
DCGM_EXPORTER_ENABLE_PRIVILEGED=""
DCGM_EXPORTER_RUNTIME_CLASS=""
DCGM_EXPORTER_ENABLE_SCC=""

# Telemetry export
EXPORT_PATCH_FILE=""
EXPORT_ENABLE_ONLY=""              # "true" | "false" | ""
EXPORT_CLEAR=false
EXPORT_SHOW=false

# Validation (telemetry patch)
SKIP_VALIDATION=false
VALIDATION_TIMEOUT=120

# Internal
SECRET_NAME="cloudera-saas-storage-config"

# ---------------------------------------------------------------------------
# Argument parsing
# ---------------------------------------------------------------------------
while [[ $# -gt 0 ]]; do
  case "$1" in
    --help)
      print_help
      exit 0
      ;;
    # --- flags that take no value ---
    --pipeline-enable)
      PIPELINE_ENABLE="true"
      shift
      ;;
    --pipeline-disable)
      PIPELINE_ENABLE="false"
      shift
      ;;
    --export-enable)
      EXPORT_ENABLE_ONLY="true"
      shift
      ;;
    --export-disable)
      EXPORT_ENABLE_ONLY="false"
      shift
      ;;
    --export-clear)
      EXPORT_CLEAR=true
      shift
      ;;
    --export-show)
      EXPORT_SHOW=true
      shift
      ;;
    --dcgm-exporter-enable)
      DCGM_EXPORTER_ENABLE="true"
      shift
      ;;
    --dcgm-exporter-disable)
      DCGM_EXPORTER_ENABLE="false"
      shift
      ;;
    --skip-validation)
      SKIP_VALIDATION=true
      shift
      ;;
    # --- flags that require an argument ---
    --storage-region | --storage-account-id | --storage-metrics-ingestion-url | --storage-dbus-api-url \
    | --storage-access-key-id | --storage-private-key | --storage-credentials-file \
    | --kubeconfig | --context | --controlplane-namespace | --pipeline-name \
    | --dcgm-exporter-node-selector \
    | --dcgm-exporter-enable-privileged | --dcgm-exporter-enable-scc \
    | --dcgm-exporter-runtime-class \
    | --export-patch | --validation-timeout)
      if [[ -z "${2:-}" || "${2:0:2}" == "--" ]]; then
        echo "❌ Error: Option '$1' requires an argument."
        print_help
        exit 1
      fi
      case "$1" in
        --storage-region)                  STORAGE_REGION="$2" ;;
        --storage-account-id)              STORAGE_ACCOUNT_ID="$2" ;;
        --storage-metrics-ingestion-url)   STORAGE_METRICS_INGESTION_URL="$2" ;;
        --storage-dbus-api-url)            STORAGE_DBUS_API_URL="$2" ;;
        --storage-access-key-id)           STORAGE_ACCESS_KEY_ID="$2" ;;
        --storage-private-key)             STORAGE_PRIVATE_KEY="$2" ;;
        --storage-credentials-file)        STORAGE_CREDENTIALS_FILE="$2" ;;
        --kubeconfig)                      KUBECONFIG_PATH="$2" ;;
        --context)                         KUBE_CONTEXT="$2" ;;
        --controlplane-namespace)          CONTROLPLANE_NAMESPACE="$2" ;;
        --pipeline-name)                   PIPELINE_NAME="$2" ;;
        --dcgm-exporter-node-selector)     DCGM_EXPORTER_NODE_SELECTOR="$2" ;;
        --dcgm-exporter-enable-privileged) DCGM_EXPORTER_ENABLE_PRIVILEGED="$2" ;;
        --dcgm-exporter-enable-scc)        DCGM_EXPORTER_ENABLE_SCC="$2" ;;
        --dcgm-exporter-runtime-class)     DCGM_EXPORTER_RUNTIME_CLASS="$2" ;;
        --export-patch)                    EXPORT_PATCH_FILE="$2" ;;
        --validation-timeout)              VALIDATION_TIMEOUT="$2" ;;
      esac
      shift 2
      ;;
    --*)
      echo "❌ Unknown option: $1"
      print_help
      exit 1
      ;;
    *)
      echo "❌ Unexpected argument: $1"
      print_help
      exit 1
      ;;
  esac
done

# ---------------------------------------------------------------------------
# Validate common required inputs
# ---------------------------------------------------------------------------
if [[ -z "$CONTROLPLANE_NAMESPACE" ]]; then
  echo "❌ Error: --controlplane-namespace is required."
  print_help
  exit 1
fi

KUBE_NAMESPACE="${CONTROLPLANE_NAMESPACE}-obs"

if [[ ! -f "$KUBECONFIG_PATH" ]]; then
  echo "❌ Error: kubeconfig file not found at '$KUBECONFIG_PATH'"
  exit 1
fi

# ---------------------------------------------------------------------------
# Validate --pipeline-enable / --pipeline-disable (values set to "true"/"false" by flag parsing)
# ---------------------------------------------------------------------------

# ---------------------------------------------------------------------------
# Validate telemetry flags for mutual exclusivity
# ---------------------------------------------------------------------------
TELEMETRY_ACTION_COUNT=0
[[ -n "$EXPORT_PATCH_FILE" ]] && TELEMETRY_ACTION_COUNT=$((TELEMETRY_ACTION_COUNT + 1))
[[ -n "$EXPORT_ENABLE_ONLY" ]] && TELEMETRY_ACTION_COUNT=$((TELEMETRY_ACTION_COUNT + 1))
[[ "$EXPORT_CLEAR" == true ]] && TELEMETRY_ACTION_COUNT=$((TELEMETRY_ACTION_COUNT + 1))
[[ "$EXPORT_SHOW" == true ]] && TELEMETRY_ACTION_COUNT=$((TELEMETRY_ACTION_COUNT + 1))

if [[ $TELEMETRY_ACTION_COUNT -gt 1 ]]; then
  echo "❌ Error: --export-patch, --export-enable/--export-disable, --export-clear, and --export-show are mutually exclusive."
  print_help
  exit 1
fi

if [[ -n "$EXPORT_PATCH_FILE" && ! -f "$EXPORT_PATCH_FILE" ]]; then
  echo "❌ Error: Telemetry patch file not found: '$EXPORT_PATCH_FILE'"
  exit 1
fi

if ! [[ "$VALIDATION_TIMEOUT" =~ ^[0-9]+$ ]]; then
  echo "❌ Error: --validation-timeout must be a positive integer."
  exit 1
fi

# ---------------------------------------------------------------------------
# Determine active modes
# ---------------------------------------------------------------------------
METRIC_STORAGE_MODE=false
DCGM_MODE=false
EXPORT_MODE=false

# Metric storage is triggered when any credentials or URL/region flags are supplied
if [[ -n "$STORAGE_ACCESS_KEY_ID" || -n "$STORAGE_PRIVATE_KEY" || -n "$STORAGE_CREDENTIALS_FILE" \
      || -n "$STORAGE_REGION" || -n "$STORAGE_ACCOUNT_ID" || -n "$STORAGE_METRICS_INGESTION_URL" || -n "$STORAGE_DBUS_API_URL" ]]; then
  METRIC_STORAGE_MODE=true
fi

# DCGM mode can run independently
if [[ -n "$DCGM_EXPORTER_ENABLE" || -n "$DCGM_EXPORTER_NODE_SELECTOR" \
      || -n "$DCGM_EXPORTER_ENABLE_PRIVILEGED" || -n "$DCGM_EXPORTER_RUNTIME_CLASS" \
      || -n "$DCGM_EXPORTER_ENABLE_SCC" ]]; then
  DCGM_MODE=true
fi

if [[ $TELEMETRY_ACTION_COUNT -gt 0 ]]; then
  EXPORT_MODE=true
fi

# Guard: ensure at least one action is requested
if [[ -z "$PIPELINE_ENABLE" && "$METRIC_STORAGE_MODE" == false \
      && "$DCGM_MODE" == false && "$EXPORT_MODE" == false ]]; then
  echo "❌ Error: No action requested. Specify metric storage flags, telemetry flags, DCGM flags, or --pipeline-enable."
  print_help
  exit 1
fi

# ---------------------------------------------------------------------------
# Validate DCGM bool flags
# ---------------------------------------------------------------------------
for _FLAG_NAME in DCGM_EXPORTER_ENABLE DCGM_EXPORTER_ENABLE_PRIVILEGED DCGM_EXPORTER_ENABLE_SCC; do
  _FLAG_VAL="${!_FLAG_NAME}"
  if [[ -n "$_FLAG_VAL" && "$_FLAG_VAL" != "true" && "$_FLAG_VAL" != "false" ]]; then
    # Map internal name back to CLI flag name for the error message
    case "$_FLAG_NAME" in
      DCGM_EXPORTER_ENABLE)            _CLI="--dcgm-exporter-enable" ;;
      DCGM_EXPORTER_ENABLE_PRIVILEGED) _CLI="--dcgm-exporter-enable-privileged" ;;
      DCGM_EXPORTER_ENABLE_SCC)        _CLI="--dcgm-exporter-enable-scc" ;;
    esac
    echo "❌ Error: ${_CLI} must be 'true' or 'false'."
    exit 1
  fi
done

# ---------------------------------------------------------------------------
# Validate --dcgm-exporter-node-selector format (KEY=VALUE)
# ---------------------------------------------------------------------------
DCGM_EXPORTER_NODE_SELECTOR_KEY=""
DCGM_EXPORTER_NODE_SELECTOR_VALUE=""
if [[ -n "$DCGM_EXPORTER_NODE_SELECTOR" ]]; then
  if [[ "$DCGM_EXPORTER_NODE_SELECTOR" != *"="* ]]; then
    echo "❌ Error: --dcgm-exporter-node-selector must be in KEY=VALUE format."
    exit 1
  fi
  DCGM_EXPORTER_NODE_SELECTOR_KEY="${DCGM_EXPORTER_NODE_SELECTOR%%=*}"
  DCGM_EXPORTER_NODE_SELECTOR_VALUE="${DCGM_EXPORTER_NODE_SELECTOR#*=}"
fi

# ---------------------------------------------------------------------------
# Validate metric storage inputs (when in metric storage mode)
# ---------------------------------------------------------------------------
if [[ "$METRIC_STORAGE_MODE" == true ]]; then
  # Read credentials from file if provided
  if [[ -n "$STORAGE_CREDENTIALS_FILE" ]]; then
    if [[ ! -f "$STORAGE_CREDENTIALS_FILE" ]]; then
      echo "❌ Error: Credentials file not found at '$STORAGE_CREDENTIALS_FILE'"
      exit 1
    fi
    STORAGE_ACCESS_KEY_ID=$(awk -F= '$1~/cdp_access_key_id/{gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2; exit}' "$STORAGE_CREDENTIALS_FILE")
    STORAGE_PRIVATE_KEY=$(awk 'index($0, "=") && $1 ~ /cdp_private_key/ { val = substr($0, index($0, "=")+1); gsub(/^[ \t]+|[ \t]+$/, "", val); print val; exit }' "$STORAGE_CREDENTIALS_FILE")
  fi

  if [[ -z "$STORAGE_ACCESS_KEY_ID" || -z "$STORAGE_PRIVATE_KEY" ]]; then
    echo "❌ Error: Credentials are required for metric storage setup."
    echo "   Provide --storage-access-key-id and --storage-private-key, or --storage-credentials-file."
    exit 1
  fi

  validate_region() { [[ "$STORAGE_REGION" =~ ^(us|eu|ap)$ ]]; }
  validate_uuid()   { [[ "$STORAGE_ACCOUNT_ID" =~ ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ ]]; }

  USE_REGION_MODE=false
  USE_URL_MODE=false
  [[ -n "$STORAGE_REGION" || -n "$STORAGE_ACCOUNT_ID" ]]  && USE_REGION_MODE=true
  [[ -n "$STORAGE_METRICS_INGESTION_URL" || -n "$STORAGE_DBUS_API_URL" ]] && USE_URL_MODE=true

  if $USE_REGION_MODE && $USE_URL_MODE; then
    echo "❌ Error: Cannot mix automatic (--storage-region/--storage-account-id) and explicit URL options."
    exit 1
  fi
  if ! $USE_REGION_MODE && ! $USE_URL_MODE; then
    echo "❌ Error: Must specify either --storage-region and --storage-account-id, OR --storage-metrics-ingestion-url and --storage-dbus-api-url."
    exit 1
  fi

  if $USE_REGION_MODE; then
    if [[ -z "$STORAGE_REGION" || -z "$STORAGE_ACCOUNT_ID" ]]; then
      echo "❌ Error: --storage-region and --storage-account-id are required together."
      exit 1
    fi
    if ! validate_region; then
      echo "❌ Error: Invalid --storage-region. Must be one of: us, eu, ap"
      exit 1
    fi
    if ! validate_uuid; then
      echo "❌ Error: Invalid --storage-account-id. Must be a valid UUID."
      exit 1
    fi
    case "$STORAGE_REGION" in
      us)
        STORAGE_METRICS_INGESTION_URL="https://receive.api.monitoring.us-west-1.cdp.cloudera.com/default/account/$STORAGE_ACCOUNT_ID/api/v1/receive"
        STORAGE_DBUS_API_URL="https://dbusapi.us-west-1.sigma.altus.cloudera.com"
        ;;
      eu)
        STORAGE_METRICS_INGESTION_URL="https://receive.api.monitoring.eu-1.cdp.cloudera.com/default/account/$STORAGE_ACCOUNT_ID/api/v1/receive"
        STORAGE_DBUS_API_URL="https://dbusapi.eu-1.cdp.cloudera.com"
        ;;
      ap)
        STORAGE_METRICS_INGESTION_URL="https://receive.api.monitoring.ap-1.cdp.cloudera.com/default/account/$STORAGE_ACCOUNT_ID/api/v1/receive"
        STORAGE_DBUS_API_URL="https://dbusapi.ap-1.cdp.cloudera.com"
        ;;
    esac
  else
    if [[ -z "$STORAGE_METRICS_INGESTION_URL" || -z "$STORAGE_DBUS_API_URL" ]]; then
      echo "❌ Error: --storage-metrics-ingestion-url and --storage-dbus-api-url are both required in direct URL mode."
      exit 1
    fi
    URL_REGEX="^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$"
    if [[ ! $STORAGE_METRICS_INGESTION_URL =~ $URL_REGEX ]]; then
      echo "❌ Error: --storage-metrics-ingestion-url must be a valid URL."
      exit 1
    fi
    if [[ ! "$STORAGE_DBUS_API_URL" =~ $URL_REGEX ]]; then
      echo "❌ Error: --storage-dbus-api-url must be a valid URL."
      exit 1
    fi
  fi
fi

# ---------------------------------------------------------------------------
# Build kubectl argument array (shared by all operations)
# ---------------------------------------------------------------------------
KUBECTL_ARGS=(--kubeconfig "$KUBECONFIG_PATH")
if [[ -n "$KUBE_CONTEXT" ]]; then
  KUBECTL_ARGS+=(--context "$KUBE_CONTEXT")
fi
KUBECTL_ARGS+=(--namespace "$KUBE_NAMESPACE")

# ---------------------------------------------------------------------------
# Helper functions
# ---------------------------------------------------------------------------

check_pipeline_exists() {
  if ! kubectl "${KUBECTL_ARGS[@]}" get ObservabilityPipeline "$PIPELINE_NAME" \
      >/dev/null 2>&1; then
    echo "❌ Error: ObservabilityPipeline '$PIPELINE_NAME' not found in namespace '$KUBE_NAMESPACE'."
    echo "   Make sure the operator is running and the CR has been created."
    exit 1
  fi
}

# Returns "true" or "false" (or empty) for spec.clouderaSaasObservability.enabled
get_saas_enabled() {
  kubectl "${KUBECTL_ARGS[@]}" get ObservabilityPipeline "$PIPELINE_NAME" \
    -o jsonpath='{.spec.clouderaSaasObservability.enabled}' 2>/dev/null || true
}

# Returns "true" or "false" (or empty) for spec.telemetryExport.enabled
get_telemetry_enabled() {
  kubectl "${KUBECTL_ARGS[@]}" get ObservabilityPipeline "$PIPELINE_NAME" \
    -o jsonpath='{.spec.telemetryExport.enabled}' 2>/dev/null || true
}

# Set spec.enabled based on the current state of sub-features.
# Called after any enable/disable operation.
update_global_enabled() {
  local saas_on telemetry_on
  saas_on=$(get_saas_enabled)
  telemetry_on=$(get_telemetry_enabled)

  if [[ "$saas_on" == "true" || "$telemetry_on" == "true" ]]; then
    echo "🔗 At least one feature is enabled — ensuring spec.enabled=true..."
    kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
      --type=merge \
      -p '{"spec": {"enabled": true}}'
  else
    echo "🔗 No features are enabled — setting spec.enabled=false..."
    kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
      --type=merge \
      -p '{"spec": {"enabled": false}}'
  fi
}

clear_telemetry_export() {
  echo "🗑️  Clearing spec.telemetryExport from '$PIPELINE_NAME'..."
  kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
    --type=merge \
    -p '{"spec": {"telemetryExport": null}}'
}

# Takes SSA ownership of spec.clouderaSaasObservability.enabled using a dedicated
# field manager so the value set here is not overwritten by the operator on upgrade
apply_saas_enabled_with_ownership() {
  local enabled_value="$1"
  kubectl "${KUBECTL_ARGS[@]}" apply \
    --server-side \
    --force-conflicts \
    --field-manager="configure-observability-pipeline" \
    -f - <<EOF
apiVersion: apps.cloudera.com/v1alpha1
kind: ObservabilityPipeline
metadata:
  name: ${PIPELINE_NAME}
  namespace: ${KUBE_NAMESPACE}
spec:
  clouderaSaasObservability:
    enabled: ${enabled_value}
EOF
}

# ---------------------------------------------------------------------------
# Mode: --export-show  (read-only; exit early before any mutations)
# ---------------------------------------------------------------------------
if [[ "$EXPORT_SHOW" == true ]]; then
  check_pipeline_exists
  echo "📋 Current spec.telemetryExport for '$PIPELINE_NAME' in '$KUBE_NAMESPACE':"
  echo ""
  BLOCK=$(kubectl "${KUBECTL_ARGS[@]}" get ObservabilityPipeline "$PIPELINE_NAME" -o yaml 2>/dev/null \
    | awk '/^  telemetryExport:/{found=1} found{if (/^[^ ]/ || (/^  [a-zA-Z]/ && !/^  telemetryExport:/)) exit; print}')
  if [[ -z "$BLOCK" ]]; then
    echo "  (not set)"
  else
    echo "$BLOCK"
  fi
  echo ""
  exit 0
fi

# ---------------------------------------------------------------------------
# Mode: --pipeline-enable  (standalone pipeline toggle; exit early)
# ---------------------------------------------------------------------------
if [[ -n "$PIPELINE_ENABLE" && "$METRIC_STORAGE_MODE" == false \
      && "$DCGM_MODE" == false && "$EXPORT_MODE" == false ]]; then
  if [[ "$PIPELINE_ENABLE" == "true" ]]; then
    echo "🚧 Starting ObservabilityPipeline..."
  else
    echo "🛑 Stopping ObservabilityPipeline..."
  fi

  check_pipeline_exists
  kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
    --type=merge \
    -p '{"spec": {"enabled": '"$PIPELINE_ENABLE"', "clouderaSaasObservability": {"enabled": '"$PIPELINE_ENABLE"'}}}'

  if [[ "$PIPELINE_ENABLE" == "true" ]]; then
    echo "✅ ObservabilityPipeline started."
  else
    echo "✅ ObservabilityPipeline stopped."
  fi
  exit 0
fi

# ---------------------------------------------------------------------------
# METRIC STORAGE SETUP
# ---------------------------------------------------------------------------
if [[ "$METRIC_STORAGE_MODE" == true ]]; then
  # Write the private key to a temp file
  STORAGE_STORAGE_PRIVATE_KEY_FILE=$(mktemp)
  printf '%b\n' "$STORAGE_PRIVATE_KEY" > "$STORAGE_STORAGE_PRIVATE_KEY_FILE"

  # Determine authentication method
  AUTH_METHOD="ed25519v1"
  if grep -q "BEGIN PRIVATE KEY" "$STORAGE_STORAGE_PRIVATE_KEY_FILE" 2>/dev/null; then
    AUTH_METHOD="rsav1"
  fi

  echo "🔐 Creating Kubernetes secret '$KUBE_NAMESPACE/$SECRET_NAME'..."

  kubectl "${KUBECTL_ARGS[@]}" create secret generic "$SECRET_NAME" \
    --from-literal=metrics-ingestion-url="$STORAGE_METRICS_INGESTION_URL" \
    --from-literal=dbus-api-url="$STORAGE_DBUS_API_URL" \
    --from-literal=access-key-id="$STORAGE_ACCESS_KEY_ID" \
    --from-file=private-key="$STORAGE_STORAGE_PRIVATE_KEY_FILE" \
    --from-literal=authentication-method="$AUTH_METHOD" \
    --dry-run=client -o yaml | kubectl "${KUBECTL_ARGS[@]}" apply -f -

  # Clean up temp file
  rm -f "$STORAGE_STORAGE_PRIVATE_KEY_FILE"

  echo "✅ Metric storage secret created successfully."

  DEPLOYMENT_NAME="${KUBE_NAMESPACE}-operator-controller-manager"

  # Scale up first if the deployment is currently at 0 replicas (operator was stopped due to any reason).
  CURRENT_REPLICAS=$(kubectl "${KUBECTL_ARGS[@]}" get deployment "$DEPLOYMENT_NAME" \
    -o jsonpath='{.spec.replicas}' 2>/dev/null || echo "0")

  if [[ "$CURRENT_REPLICAS" -eq 0 ]]; then
    echo "🚀 Operator is scaled down — scaling up to 1 replica..."
    kubectl "${KUBECTL_ARGS[@]}" scale deployment "$DEPLOYMENT_NAME" --replicas=1
  else
    echo "🔄 Operator already running — performing rollout restart to pick up new configurations..."
    kubectl "${KUBECTL_ARGS[@]}" rollout restart deployment "$DEPLOYMENT_NAME"
  fi

  echo "⏳ Waiting for Observability Operator deployment to be ready..."
  kubectl "${KUBECTL_ARGS[@]}" wait deployment "$DEPLOYMENT_NAME" \
    --for=condition=Available \
    --timeout=300s

  echo "✅ Observability Operator started."

  # Wait for the ObservabilityPipeline CR to be created
  echo "⏳ Waiting for ObservabilityPipeline CR '$PIPELINE_NAME' to be created..."
  MAX_RETRIES=60
  RETRY_COUNT=0
  while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do
    if kubectl "${KUBECTL_ARGS[@]}" get ObservabilityPipeline "$PIPELINE_NAME" >/dev/null 2>&1; then
      echo "✅ ObservabilityPipeline CR found."
      break
    fi
    RETRY_COUNT=$((RETRY_COUNT + 1))
    if [[ $RETRY_COUNT -ge $MAX_RETRIES ]]; then
      echo "❌ Error: Timeout waiting for ObservabilityPipeline CR to be created."
      exit 1
    fi
    sleep 1
  done

  echo "🔧 Enabling Cloudera SaaS Observability..."
  apply_saas_enabled_with_ownership "true"
  kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
    --type=merge \
    -p '{"spec": {"enabled": true}}'

  echo "✅ Metric storage configured and Cloudera SaaS Observability enabled."
fi

# ---------------------------------------------------------------------------
# DCGM EXPORTER CONFIGURATION  (independent of full metric storage setup)
# ---------------------------------------------------------------------------
if [[ "$DCGM_MODE" == true ]]; then
  check_pipeline_exists

  if [[ -n "$DCGM_EXPORTER_ENABLE" ]]; then
    echo "🔧 Configuring DCGM Exporter (enabled=$DCGM_EXPORTER_ENABLE)..."
    kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
      --type=merge \
      -p '{"spec": {"dcgmExporter": {"enabled": '"$DCGM_EXPORTER_ENABLE"'}}}'
  fi

  if [[ -n "$DCGM_EXPORTER_NODE_SELECTOR_KEY" && -n "$DCGM_EXPORTER_NODE_SELECTOR_VALUE" ]]; then
    echo "🔧 Setting nodeSelector for DCGM Exporter ($DCGM_EXPORTER_NODE_SELECTOR_KEY=$DCGM_EXPORTER_NODE_SELECTOR_VALUE)..."
    kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
      --type=json \
      -p='[
        {
          "op": "replace",
          "path": "/spec/dcgmExporter/k8sWorkloadSpec/overrides/spec/template/spec/nodeSelector",
          "value": {
            "'"$DCGM_EXPORTER_NODE_SELECTOR_KEY"'": "'"$DCGM_EXPORTER_NODE_SELECTOR_VALUE"'"
          }
        }
      ]'
  fi

  if [[ -n "$DCGM_EXPORTER_ENABLE_PRIVILEGED" ]]; then
    echo "🔧 Setting DCGM Exporter privileged context ($DCGM_EXPORTER_ENABLE_PRIVILEGED)..."
    kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
      --type=merge \
      -p '{"spec": {"dcgmExporter": {"k8sWorkloadSpec": {"overrides": {"spec": {"template": {"spec": {"containers": [{"name": "dcgm-exporter", "securityContext": {"privileged": '"$DCGM_EXPORTER_ENABLE_PRIVILEGED"'}}]}}}}}}}}'
  fi

  if [[ -n "$DCGM_EXPORTER_RUNTIME_CLASS" ]]; then
    echo "🔧 Setting runtimeClassName for DCGM Exporter ($DCGM_EXPORTER_RUNTIME_CLASS)..."
    kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
      --type=merge \
      -p '{"spec": {"dcgmExporter": {"k8sWorkloadSpec": {"overrides": {"spec": {"template": {"spec": {"runtimeClassName": "'"$DCGM_EXPORTER_RUNTIME_CLASS"'"}}}}}}}}'
  fi

  if [[ -n "$DCGM_EXPORTER_ENABLE_SCC" ]]; then
    if [[ "$DCGM_EXPORTER_ENABLE_SCC" == "true" ]]; then
      echo "🔧 Applying DCGM Exporter SecurityContextConstraints..."
      kubectl "${KUBECTL_ARGS[@]}" apply -f - <<EOF
kind: SecurityContextConstraints
metadata:
  annotations:
  name: ${KUBE_NAMESPACE}-dcgm-scc
readOnlyRootFilesystem: false
runAsUser:
  type: RunAsAny
seLinuxContext:
  type: RunAsAny
seccompProfiles:
- '*'
supplementalGroups:
  type: RunAsAny
users:
- system:serviceaccount:${KUBE_NAMESPACE}:${KUBE_NAMESPACE}-dcgm-exporter
- '*'
allowHostDirVolumePlugin: true
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: true
allowPrivilegeEscalation: true
allowPrivilegedContainer: true
allowedCapabilities:
- '*'
- '*'
apiVersion: security.openshift.io/v1
defaultAddCapabilities: null
fsGroup:
  type: RunAsAny
groups:
- system:cluster-admins
- system:nodes
- system:masters
EOF
    else
      echo "🗑️  Removing DCGM Exporter SecurityContextConstraints..."
      kubectl "${KUBECTL_ARGS[@]}" delete scc "${KUBE_NAMESPACE}-dcgm-scc" || true
    fi
  fi

  echo "✅ DCGM Exporter configuration applied."
fi

# ---------------------------------------------------------------------------
# TELEMETRY EXPORT OPERATIONS
# ---------------------------------------------------------------------------
if [[ "$EXPORT_MODE" == true ]]; then
  check_pipeline_exists

  # ---- clear ----
  if [[ "$EXPORT_CLEAR" == true ]]; then
    clear_telemetry_export
    update_global_enabled
    echo "✅ Telemetry export configuration cleared."
    # Skip further telemetry processing
    EXPORT_MODE=false
  fi

  # ---- enable / disable ----
  if [[ -n "$EXPORT_ENABLE_ONLY" ]]; then
    if [[ "$EXPORT_ENABLE_ONLY" == "true" ]]; then
      echo "▶️  Enabling telemetry export..."
    else
      echo "⏹️  Disabling telemetry export..."
    fi

    kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
      --type=merge \
      -p '{"spec": {"telemetryExport": {"enabled": '"$EXPORT_ENABLE_ONLY"'}}}'

    update_global_enabled

    if [[ "$EXPORT_ENABLE_ONLY" == "true" ]]; then
      echo "✅ Telemetry export enabled."
    else
      echo "✅ Telemetry export disabled."
    fi
    EXPORT_MODE=false
  fi

  # ---- apply patch file ----
  if [[ -n "$EXPORT_PATCH_FILE" ]]; then
    # Clear first so that components removed from the new config do not linger:
    # kubectl patch --type=merge cannot remove list elements.
    clear_telemetry_export
    echo "   Done."

    echo "📄 Applying telemetry export configuration from '$EXPORT_PATCH_FILE'..."
    kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
      --type=merge \
      --patch-file "$EXPORT_PATCH_FILE"

    echo "✅ Telemetry export configuration applied."

    # The patch presumably enables telemetry export; reflect that in the global flag
    update_global_enabled

    # ---- Optional validation ----
    if [[ "$SKIP_VALIDATION" == true ]]; then
      echo "⏭️  Skipping post-apply validation (--skip-validation)."
    else
      echo ""
      echo "🔍 Running post-apply validation..."

      echo ""
      echo "📋 Checking operator logs for reconciliation errors..."

      OPERATOR_LABEL="app.kubernetes.io/name=observability-operator"
      OPERATOR_POD=$(kubectl "${KUBECTL_ARGS[@]}" get pod \
        -l "$OPERATOR_LABEL" \
        -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true)

      VALIDATION_PASSED=true

      if [[ -z "$OPERATOR_POD" ]]; then
        echo "   ⚠️  Warning: Could not find operator pod (label: $OPERATOR_LABEL). Skipping log check."
      else
        sleep 3
        LOG_TMP=$(mktemp)
        kubectl "${KUBECTL_ARGS[@]}" logs "$OPERATOR_POD" \
          --since=60s 2>/dev/null \
          | perl -pe 's/\x1b\[[0-9;]*m//g' > "$LOG_TMP" || true

        OPERATOR_ERRORS=$(grep -E ' ERR ' "$LOG_TMP" || true)
        rm -f "$LOG_TMP"

        if [[ -n "$OPERATOR_ERRORS" ]]; then
          echo "   ❌ Operator logged reconciliation errors:"
          printf '%s\n' "$OPERATOR_ERRORS" | head -20 | while IFS= read -r line; do echo "      $line"; done
          echo ""
          echo "⚠️  Validation failed due to operator errors. Collector pods may not have been updated."
          echo "   You can re-run validation at any time or inspect the cluster manually:"
          echo "   kubectl logs -n $KUBE_NAMESPACE $OPERATOR_POD"
          echo "   kubectl get pods -n $KUBE_NAMESPACE -l app.kubernetes.io/component=opentelemetry-collector"
          exit 1
        else
          echo "   ✅ No errors found in recent operator logs."
        fi
      fi

      echo ""
      echo "⏳ Waiting up to ${VALIDATION_TIMEOUT}s for collector pods to be healthy..."

      COLLECTOR_LABEL="app.kubernetes.io/component=opentelemetry-collector"
      DEADLINE=$(( $(date +%s) + VALIDATION_TIMEOUT ))
      PODS_HEALTHY=false
      FATAL_STATES="CreateContainerConfigError|CrashLoopBackOff|Error|OOMKilled|ImagePullBackOff|ErrImagePull"

      while [[ $(date +%s) -lt $DEADLINE ]]; do
        ALL_PODS=$(kubectl "${KUBECTL_ARGS[@]}" get pods \
          -l "$COLLECTOR_LABEL" \
          --no-headers \
          -o custom-columns=\
'NAME:.metadata.name,READY:.status.containerStatuses[0].ready,RESTARTS:.status.containerStatuses[0].restartCount,PHASE:.status.phase,DELETE:.metadata.deletionTimestamp,REASON:.status.containerStatuses[0].state.waiting.reason' \
          2>/dev/null || true)

        if [[ -z "$ALL_PODS" ]]; then
          echo "   ⚠️  No collector pods found yet, retrying..."
          sleep 5
          continue
        fi

        FATAL=$(awk -v states="$FATAL_STATES" '$6 ~ states {print $1 " (" $6 ")"}' <<< "$ALL_PODS" || true)
        if [[ -n "$FATAL" ]]; then
          echo ""
          echo "   ❌ Collector pod(s) entered a fatal state:"
          while IFS= read -r line; do echo "      $line"; done <<< "$FATAL"
          VALIDATION_PASSED=false
          break
        fi

        TERMINATING=$(awk '$5 != "<none>" {print $1}' <<< "$ALL_PODS" || true)
        LIVE_PODS=$(awk '$5 == "<none>" {print}' <<< "$ALL_PODS" || true)
        UNREADY=$(awk '$2 != "true" || $3 > 2 {print $1}' <<< "$LIVE_PODS" || true)

        if [[ -n "$TERMINATING" ]]; then
          echo "   ⏳ Pods still terminating: $(tr '\n' ' ' <<< "$TERMINATING")"
          sleep 3
          continue
        fi

        if [[ -n "$UNREADY" || -z "$LIVE_PODS" ]]; then
          echo "   ⏳ Pods not yet ready: $(tr '\n' ' ' <<< "$UNREADY")"
          sleep 5
          continue
        fi

        PODS_HEALTHY=true
        echo "   ✅ All collector pods are healthy:"
        while IFS= read -r line; do echo "      $line"; done <<< "$LIVE_PODS"
        break
      done

      if [[ "$PODS_HEALTHY" == false ]]; then
        echo ""
        echo "   ❌ Collector pods did not become healthy within ${VALIDATION_TIMEOUT}s."
        echo "      Current pod state:"
        kubectl "${KUBECTL_ARGS[@]}" get pods -l "$COLLECTOR_LABEL" \
          --no-headers 2>/dev/null | while IFS= read -r line; do echo "        $line"; done || true
        echo ""
        echo "      Recent pod events:"
        kubectl "${KUBECTL_ARGS[@]}" get events \
          --field-selector reason=BackOff \
          --sort-by='.lastTimestamp' 2>/dev/null | tail -10 | while IFS= read -r line; do echo "        $line"; done || true
        VALIDATION_PASSED=false
      fi

      echo ""
      if [[ "$VALIDATION_PASSED" == true ]]; then
        echo "✅ Validation passed. Telemetry export configuration is active and healthy."
      else
        echo "⚠️  Validation completed with warnings. Review the output above."
        echo "   You can re-run validation at any time or inspect the cluster manually:"
        echo "   kubectl logs -n $KUBE_NAMESPACE $OPERATOR_POD"
        echo "   kubectl get pods -n $KUBE_NAMESPACE -l $COLLECTOR_LABEL"
        exit 1
      fi
    fi
  fi
fi

# ---------------------------------------------------------------------------
# If --pipeline-enable was also specified alongside other operations, apply it
# last as an explicit override.
# ---------------------------------------------------------------------------
if [[ -n "$PIPELINE_ENABLE" ]]; then
  if [[ "$PIPELINE_ENABLE" == "true" ]]; then
    echo "🚧 Applying --pipeline-enable override..."
  else
    echo "🛑 Applying --pipeline-disable override..."
  fi

  kubectl "${KUBECTL_ARGS[@]}" patch ObservabilityPipeline "$PIPELINE_NAME" \
    --type=merge \
    -p '{"spec": {"enabled": '"$PIPELINE_ENABLE"', "clouderaSaasObservability": {"enabled": '"$PIPELINE_ENABLE"'}}}'

  if [[ "$PIPELINE_ENABLE" == "true" ]]; then
    echo "✅ ObservabilityPipeline enabled."
  else
    echo "✅ ObservabilityPipeline disabled."
  fi
fi

