{{- /*
Copyright Broadcom, Inc. All Rights Reserved.
SPDX-License-Identifier: APACHE-2.0
*/}}

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ printf "%s-hooks-scripts" (include "postgresql-ha.postgresql" .) }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
    app.kubernetes.io/component: postgresql
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
data:
  pre-stop.sh: |-
    #!/bin/bash
    set -o errexit
    set -o pipefail
    set -o nounset

    # Debug section
    exec 3>&1
    exec 4>&2

    # Process input parameters
    MIN_DELAY_AFTER_PG_STOP_SECONDS=$1

    # Load Libraries
    . /opt/bitnami/scripts/liblog.sh
    . /opt/bitnami/scripts/libpostgresql.sh
    . /opt/bitnami/scripts/librepmgr.sh

    # Load PostgreSQL & repmgr environment variables
    . /opt/bitnami/scripts/postgresql-env.sh

    # Auxiliary functions
    is_new_primary_ready() {
        return_value=1
        currenty_primary_node="$(repmgr_get_primary_node)"
        currenty_primary_host="$(echo $currenty_primary_node | awk '{print $1}')"

        info "$currenty_primary_host != $REPMGR_NODE_NETWORK_NAME"
        if [[ $(echo $currenty_primary_node | wc -w) -eq 2 ]] && [[ "$currenty_primary_host" != "$REPMGR_NODE_NETWORK_NAME" ]]; then
            info "New primary detected, leaving the cluster..."
            return_value=0
        else
            info "Waiting for a new primary to be available..."
        fi
        return $return_value
    }

    export MODULE="pre-stop-hook"

    if [[ "${BITNAMI_DEBUG}" == "true" ]]; then
        info "Bash debug is on"
    else
        info "Bash debug is off"
        exec 1>/dev/null
        exec 2>/dev/null
    fi

    postgresql_enable_nss_wrapper

    # Prepare env vars for managing roles
    readarray -t primary_node < <(repmgr_get_upstream_node)
    primary_host="${primary_node[0]}"

    # Stop postgresql for graceful exit.
    PG_STOP_TIME=$EPOCHSECONDS
    postgresql_stop

    if [[ -z "$primary_host" ]] || [[ "$primary_host" == "$REPMGR_NODE_NETWORK_NAME" ]]; then
        info "Primary node need to wait for a new primary node before leaving the cluster"
        retry_while is_new_primary_ready 10 5
    else
        info "Standby node doesn't need to wait for a new primary switchover. Leaving the cluster"
    fi

    # Make sure pre-stop hook waits at least 25 seconds after stop of PG to make sure PGPOOL detects node is down.
    # default terminationGracePeriodSeconds=30 seconds
    PG_STOP_DURATION=$(($EPOCHSECONDS - $PG_STOP_TIME))
    if (( $PG_STOP_DURATION < $MIN_DELAY_AFTER_PG_STOP_SECONDS )); then
        WAIT_TO_PG_POOL_TIME=$(($MIN_DELAY_AFTER_PG_STOP_SECONDS - $PG_STOP_DURATION)) 
        info "PG stopped including primary switchover in $PG_STOP_DURATION. Waiting additional $WAIT_TO_PG_POOL_TIME seconds for PG pool"
        sleep $WAIT_TO_PG_POOL_TIME
    fi

  readiness-probe.sh: |-
    #!/bin/bash
    set -o errexit
    set -o pipefail
    set -o nounset

    # Debug section
    exec 3>&1
    exec 4>&2

    # Load Libraries
    . /opt/bitnami/scripts/liblog.sh
    . /opt/bitnami/scripts/libpostgresql.sh

    # Load PostgreSQL & repmgr environment variables
    . /opt/bitnami/scripts/postgresql-env.sh

    # Process input parameters
    MIN_DELAY_AFTER_POD_READY_FIRST_TIME=$1
    TMP_FIRST_READY_FILE_TS="/tmp/ts-first-ready.mark"
    TMP_DELAY_APPLIED_FILE="/tmp/delay-applied.mark"

    DB_CHECK_RESULT=$(echo "SELECT 1" | postgresql_execute_print_output "$POSTGRESQL_DATABASE" "$POSTGRESQL_USERNAME" "$POSTGRESQL_PASSWORD" "-h 127.0.0.1 -tA" || echo "command failed")
    if [[ "$DB_CHECK_RESULT" == "1" ]]; then
      if [[ ! -f "$TMP_DELAY_APPLIED_FILE" ]]; then
        # DB up, but initial readiness delay not applied
        if [[ -f "$TMP_FIRST_READY_FILE_TS" ]]; then
          # calculate delay from the first readiness success
          FIRST_READY_TS=$(cat $TMP_FIRST_READY_FILE_TS)
          CURRENT_DELAY_SECONDS=$(($EPOCHSECONDS - $FIRST_READY_TS))
          if (( $CURRENT_DELAY_SECONDS > $MIN_DELAY_AFTER_POD_READY_FIRST_TIME )); then
            # minimal delay of the first readiness state passed - report success and mark delay as applied
            touch "$TMP_DELAY_APPLIED_FILE"
          else
            # minimal delay of the first readiness state not reached yet - report failure
            exit 1
          fi
        else
          # first ever readiness test success - store timestamp and report failure
          echo $EPOCHSECONDS > $TMP_FIRST_READY_FILE_TS
          exit 1
        fi
      fi
    else
      # DB test failed - report failure
      exit 1
    fi
