#!/usr/bin/env bash

set -euo pipefail

ACTION=""
NAMESPACE=""
DRY_RUN=false

usage() {
    cat <<EOF
Uso:

  $0 hibernate [--namespace NAMESPACE] [--dry-run]
  $0 resume    [--namespace NAMESPACE] [--dry-run]

Esempi:

  # Mostra cosa verrebbe ibernato in tutti i namespace
  $0 hibernate --dry-run

  # Iberna tutti i cluster CNPG
  $0 hibernate

  # Iberna solo i cluster di un namespace
  $0 hibernate --namespace produzione

  # Mostra cosa verrebbe riattivato
  $0 resume --dry-run

  # Riattiva tutti i cluster CNPG
  $0 resume

EOF
}

#
# Parsing argomenti
#
if [[ $# -lt 1 ]]; then
    usage
    exit 1
fi

ACTION="$1"
shift

case "$ACTION" in
    hibernate|resume)
        ;;
    *)
        echo "Errore: azione non valida: $ACTION"
        usage
        exit 1
        ;;
esac

while [[ $# -gt 0 ]]; do
    case "$1" in
        --namespace|-n)
            NAMESPACE="$2"
            shift 2
            ;;
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        --help|-h)
            usage
            exit 0
            ;;
        *)
            echo "Errore: parametro sconosciuto: $1"
            usage
            exit 1
            ;;
    esac
done

#
# Controlli prerequisiti
#
command -v kubectl >/dev/null 2>&1 || {
    echo "Errore: kubectl non trovato"
    exit 1
}

kubectl cnpg version >/dev/null 2>&1 || {
    echo "Errore: plugin kubectl-cnpg non disponibile o non funzionante"
    exit 1
}

#
# Recupero cluster CNPG
#
# label applicata dallo script per tracciare le ibernazioni proprie
SCRIPT_LABEL="cnpg-maintenance-hibernated"

JSONPATH='{range .items[*]}{.metadata.namespace}{";"}{.metadata.name}{";"}{.status.readyInstances}{";"}{.metadata.annotations.cnpg\.io/hibernation}{";"}{.metadata.labels.cnpg-maintenance-hibernated}{"\n"}{end}'

if [[ -n "$NAMESPACE" ]]; then

    CLUSTERS=$(kubectl get cluster.postgresql.cnpg.io \
        -n "$NAMESPACE" \
        -o jsonpath="$JSONPATH")

else

    CLUSTERS=$(kubectl get cluster.postgresql.cnpg.io \
        -A \
        -o jsonpath="$JSONPATH")

fi

if [[ -z "$CLUSTERS" ]]; then
    echo "Nessun cluster CNPG trovato."
    exit 0
fi

echo
echo "========================================"
echo " CNPG BULK OPERATION"
echo "========================================"
echo "Azione:    $ACTION"

if [[ -n "$NAMESPACE" ]]; then
    echo "Namespace: $NAMESPACE"
else
    echo "Namespace: TUTTI"
fi

echo "Dry-run:   $DRY_RUN"
echo "========================================"
echo

#
# Elaborazione cluster
#
while IFS=";" read -r NS CLUSTER READY_INSTANCES HIBERNATION_ANNOTATION SCRIPT_HIBERNATED; do

    [[ -z "$CLUSTER" ]] && continue

    if [[ "$ACTION" == "hibernate" ]]; then
        # skip clusters con no ready instances (già ibernati o non attivi)
        if [[ -z "$READY_INSTANCES" || "$READY_INSTANCES" -lt 1 ]]; then
            echo "Cluster: $NS/$CLUSTER — SALTATO (readyInstances=${READY_INSTANCES:-0}, già ibernato o non attivo)"
            echo
            continue
        fi
    else
        # resume: solo cluster ibernati da questo script (label presente) e con annotazione CNPG attiva
        if [[ "$SCRIPT_HIBERNATED" != "true" || "$HIBERNATION_ANNOTATION" != "on" ]]; then
            echo "Cluster: $NS/$CLUSTER — SALTATO (non ibernato da questo script)"
            echo
            continue
        fi
    fi

    echo "Cluster: $NS/$CLUSTER (readyInstances=${READY_INSTANCES:-0}, hibernation=${HIBERNATION_ANNOTATION:-none}, script-label=${SCRIPT_HIBERNATED:-none})"

    if [[ "$ACTION" == "hibernate" ]]; then

        CMD=(
            kubectl
            cnpg
            hibernate
            on
            "$CLUSTER"
            -n
            "$NS"
        )

    else

        CMD=(
            kubectl
            cnpg
            hibernate
            off
            "$CLUSTER"
            -n
            "$NS"
        )

    fi

    if [[ "$DRY_RUN" == true ]]; then

        echo "[DRY-RUN] ${CMD[*]}"
        if [[ "$ACTION" == "hibernate" ]]; then
            echo "[DRY-RUN] kubectl label cluster.postgresql.cnpg.io $CLUSTER -n $NS ${SCRIPT_LABEL}=true"
        else
            echo "[DRY-RUN] kubectl label cluster.postgresql.cnpg.io $CLUSTER -n $NS ${SCRIPT_LABEL}-"
        fi

    else

        echo "Esecuzione: ${CMD[*]}"

        if "${CMD[@]}"; then
            echo "OK: $NS/$CLUSTER"
            if [[ "$ACTION" == "hibernate" ]]; then
                kubectl label cluster.postgresql.cnpg.io "$CLUSTER" -n "$NS" "${SCRIPT_LABEL}=true" --overwrite
            else
                kubectl label cluster.postgresql.cnpg.io "$CLUSTER" -n "$NS" "${SCRIPT_LABEL}-"
            fi
        else
            echo "ERRORE: $NS/$CLUSTER"
        fi

    fi

    echo

done <<< "$CLUSTERS"

echo "========================================"
echo "Operazione completata"
echo "========================================"