#!/usr/bin/env bash
# Puppet Apply TASK
# Description: Applies a configuration fetched from the ADMIN_URL onto the server using puppet apply

main() {
  . $(dirname $0)/oio-ga-tools-utils
  TASK="PUPPET_APPLY"
  PROGNAME=$(basename "$0")

  # lock $PROGNAME 201 || eexit "ERROR: Cannot run: $PROGNAME - lock file exists"

  if [ -z "$1" ]; then
    log "ERROR" $TASK" requires an url specified with -u"
    exit 1
  fi

  MODULE="config"
  NOEXEC=false
  USE_V2=false

  while getopts ":u:n:m:ev" opt; do
    case $opt in
      n)
        CURRENT_NAMESPACE=$OPTARG
        ;;
      u)
        ADMIN_URL=$OPTARG
        ;;
      v)
        USE_V2=true
        ;;
      m)
        MODULE=$OPTARG
        ;;
      e)
        NOEXEC=true
        ;;
      \?)
        log "WARN" "Invalid option provided -$OPTARG"
        exit 1
        ;;
      :)
        log "WARN" "Option -$OPTARG requires argument."
        exit 1
        ;;
    esac
  done

  HOST=$(hostname --short)
  ADMIN_ROUTE="${ADMIN_URL}/api/servers/${HOST}/namespaces/$CURRENT_NAMESPACE/services/$MODULE.pp"
  if $USE_V2 && [ "$MODULE" == "config" ]; then
    ADMIN_ROUTE="${ADMIN_URL}/api/v2/namespaces/$CURRENT_NAMESPACE/servers/${HOST}/$MODULE.pp?separator=sp"
  fi
  CONFIG_DIR="/etc/oio/sds/oio-puppetapply"

  if [ -z "$(puppet)" ]; then
    log "ERROR" "No puppet binary found."
    exit 1
  fi

  # Lock
  mkdir -p "$CONFIG_DIR"

  log "INFO" "Fetching and creating volume directories"
  DIR_ROUTE="${ADMIN_URL}/api/v2/namespaces/$CURRENT_NAMESPACE/servers/${HOST}/dirs-to-create"
  dirs=$(curl -s -f "$DIR_ROUTE")
  dirs=${dirs:1:-1}
  $(mkdir -p $dirs) || echo "No directories to create"
  log "INFO" "Created: $dirs"

  # Download config file
  log "INFO" "Attempting configuration download at ${ADMIN_ROUTE}"
  curl -XGET ${ADMIN_ROUTE} -S -f -s -o "$CONFIG_DIR/$MODULE_tmp.pp" || (log "ERROR" "Download failure. Exiting"; exit 1)

  # Format the string inside the file
  awk '{print substr($0,2,length()-2);}' $CONFIG_DIR/$MODULE_tmp.pp > $CONFIG_DIR/$MODULE.pp
  log "INFO" "Download successful. Configuration path: $CONFIG_DIR/$MODULE.pp"

  log "INFO" "Applying configuration for the namespace $CURRENT_NAMESPACE"

  # Validate the configuration file
  log "INFO" "Validating configuration"
  res=$(puppet parser validate $CONFIG_DIR/$MODULE.pp)

  if [ -n "$res" ]; then
     log "ERROR" "Invalid configuration file: \n {$res}"
     rm -f "$CONFIG_DIR/$MODULE.pp" "$CONFIG_DIR/$MODULE_tmp.pp"
     exit 1
  else
    log "INFO" "Configuration is valid"
    if [ -z "$3" ]; then
      res=$(puppet apply --show_diff --no-stringify_facts --noop "$CONFIG_DIR/$MODULE.pp")
      log "INFO" "Changelog:\n"
      log "INFO" "$res"
      log "INFO" "Configuration test passed."
    fi
    log "INFO" "Starting puppet apply"
  fi

  mkdir -p /run/oio
  # Apply configuration (add --noop --show_diff for DRY RUN)
  log "INFO" `puppet apply --verbose --no-stringify_facts "$CONFIG_DIR/$MODULE.pp"`
  log "INFO" "Puppet apply done"
  # Restart the conscienceagent service
  if [ "$MODULE" == "config" ]; then
    if $NOEXEC ; then
      if [[ -z $(ps -e | grep gridinit) ]]; then
        log "INFO" "Starting gridinit"
        gridinit -d /etc/gridinit.conf || log "WARN" "Gridinit started"
      fi
      sleep 2
      gridinit_cmd start @$CURRENT_NAMESPACE || echo "Services already running"
    fi
    SID=$(gridinit_cmd status | grep $CURRENT_NAMESPACE | grep conscienceagent | awk '{ print $1 }')
    log "INFO" "Restarting conscience agent ($SID)"
    gridinit_cmd reload
    gridinit_cmd restart $SID &> /dev/null
  fi
  log "INFO" "Configuration applied"
  # unlock $PROGNAME 201
  exit 0
}

. $(dirname $0)/oio-ga-tools-logger main "$@"
