#!/bin/bash
# Purpose: user interface for configuration management system
################################################################################

set -e
set -u

if [ "$UID" -ne 0 ] ; then
  printf "Error: ngcpcfg requires root permissions. Exiting.\n" >&2
  exit 1
fi

# support for testsuite
FUNCTIONS="${FUNCTIONS:-/usr/share/ngcp-ngcpcfg/functions/}"
SCRIPTS="${SCRIPTS:-/usr/share/ngcp-ngcpcfg/scripts/}"

if ! [ -r "${FUNCTIONS}/main" ] ; then
  printf "Error: %s/main could not be read. Exiting.\n" "${FUNCTIONS}" >&2
  exit 1
fi

if [[ "${1:-}" == "decrypt" ]] ; then
  # do NOT source ${FUNCTIONS}/main but just provide
  # the part we need for executing ngcpcfg itself
  log_debug() {
    if [ -n "${DEBUG:-}" ] ; then
      logger -t ngcpcfg -- "Debug: $*"
      echo ; echo "DEBUG: $*" ; echo # newlines to avoid messup with cmdline output
    fi
  }
else
  . "${FUNCTIONS}"/main
fi

# helper functions

action() {
  ACTION="$1"
  shift
  log_debug "${SCRIPTS}/${ACTION} $*"
  "${SCRIPTS}/${ACTION}" "$@"
}

usage() {
  # make sure to output errors on stderr
  [ "${1:-}" = "1" ] && exec >&2

  printf "%s - Configuration Management System\n\n" "$PN"
  printf "Usage: %s <action> [<opts>]

Actions:
  check [<path>]      validate YAML configuration files
  build [<opts>]      generate/update configuration files
  services [<opts>]   execute service handlers for modified configuration files
  commit [<msg>]      commit and record changes (without pushing)
  apply [<msg>]       a short-cut for build-services-commit
  diff [<opts>]       display pending configuration changes
  status [<opts>]     display status of configuration file
  log [<opts>]        show log of config changes
  show [<id>]         show latest config change (or <id> if specified)
  clean [<opts>]      clean /etc/ngcp-config folder configs/templates (see available options)
  set [<opts>]        set YAML option in defined file
  del [<opts>]        delete YAML option from defined file
" "$PN"

  # display only if ngcp-ngcpcfg-ha is available
  if [ -r /usr/share/ngcp-ngcpcfg/functions/ha_features ] ; then
    printf "  push [<opts>]       push modifications to other systems (shared storage setup only)\n"
    printf "  pull                retrieve modifications from shared storage (shared storage setup only)\n"
  fi

  # display only if ngcp-ngcpcfg-locker is available
  if [ -r /usr/share/ngcp-ngcpcfg/scripts/encrypt ] ; then
    printf "  encrypt             encrypt /etc/ngcp-config and all resulting configuration files\n"
    printf "  decrypt             decrypt /etc/ngcp-config-crypted.tgz.gpg and restore config files\n"
  fi

  printf "\
  initialise          initialise setup (to be executed only once on setup)
"

  # display only if ngcp-ngcpcfg-carrier is available
  if [ -r /usr/share/ngcp-ngcpcfg/scripts/init-mgmt ] ; then
    printf "  init-mgmt <srv>     set up mgmt server for carrier environment (to be executed only once)\n"
  fi

  printf "\
  values <key>        print key value from YAML configuration files
  help                display this help screen and exit
  version             display program version and exit
\n"

  printf "For further usage information and options see the ngcpcfg(8) man page.\n"
}

version() {
  versinfo=$(dpkg-query -f "\${Version}" -W ngcp-ngcpcfg 2>/dev/null)
  [ -n "${versinfo:-}" ] || versinfo='information not available'
  printf "ngcpcfg, version %s\n" "${versinfo}"
}

case ${1:-} in
  apply|\
  build|\
  check|\
  clean|\
  commit|\
  decrypt|\
  diff|\
  encrypt|\
  init-mgmt|\
  initialise|\
  log|\
  pull|\
  push|\
  services|\
  show|\
  status|\
  values|\
  set|\
  del)
    action "$@" ;;
  --debug)         export DEBUG=1 ;      shift ; "$0" "$@" ;;
  --no-db-sync)    export NO_DB_SYNC=1 ; shift ; "$0" "$@" ;;
  --no-validate)   export NO_VALIDATE=1; shift ; "$0" "$@" ;;
  --no-action-failure) export NO_ACTION_FAILURE=1; shift ; "$0" "$@" ;;
  --validate)   export VALIDATE=1; shift ; "$0" "$@" ;;
  -h|--help|help)       usage   ; exit 0;;
  -v|--version|version) version ; exit 0;;
  *)          usage 1; exit 1;;
esac

## END OF FILE #################################################################
