#!/bin/bash

set -e

enable_lb=false
enable_proxy=false
enable_sbc=false
enable_rtp=false
set_level=false
sems_level="not available"
lb_level="not available"
proxy_level="not available"
rtp_level="not available"
rtp_systems=()
declare -A rtp_def_loglevel
declare -A rtp_system_description
declare -A rtpengine_opt

if [ "$(id -u 2>/dev/null)" != 0 ] ; then
  echo "Error: this script requires root permissions." >&2
  exit 1
fi

# load config
if ! [ -r /etc/default/ngcp-roles ] ; then
  echo "Warning: cannot read /etc/default/ngcp-roles" >&2
  exit 1
fi

# shellcheck disable=SC1091
. /etc/default/ngcp-roles

if ! /usr/sbin/ngcp-check-active -q ; then
  echo "Please run the script on active node" >&2
  exit 1
fi

# enable components
if [ "$NGCP_IS_LB" = "yes" ]; then
  enable_lb=true
fi
if [[ "$NGCP_IS_RTP" = "yes" && $(pidof rtpengine) ]]; then
  enable_rtp=true
fi
if [ "$NGCP_IS_PROXY" = "yes" ]; then
  enable_proxy=true
  enable_sbc=true
  if  [ "$NGCP_TYPE" = "spce" ]; then
    sems_ip=$(awk -F= '/sip_ip/{print $2;exit;}' /etc/ngcp-sems/sems.conf)
    sbc_port=$(awk -F= '/monit_udp_port/{print $2;exit;}' /etc/ngcp-sems/etc/stats.conf)
  else
    sems_ip=$(awk -F= '/sip_ip/{print $2;exit;}' /etc/sems-b2b/sems.conf)
    sbc_port=$(awk -F= '/monit_udp_port/{print $2;exit;}' /etc/sems-b2b/etc/stats.conf)
  fi
fi

#----- Setting variables -----
COMPONENT=$1
PARAM=$2
if [ "$COMPONENT" = "rtpengine" ]; then
  case "$PARAM" in
    -*)
      RTPENGINE_SYS=all
      ;;
    *)
      RTPENGINE_SYS=$2
      PARAM=$3
      ;;
  esac
fi
if  [ "$NGCP_TYPE" = "spce" ]; then
  sems_command=(ngcp-sems-stats -s "${sems_ip}" -p "${sbc_port}")
else
  sems_command=(sems-b2b-stats -s "${sems_ip}" -p "${sbc_port}")
fi
rtpengine_command=(rtpengine-ctl)

if "${enable_rtp}" ; then
  while IFS=' - ' read -r rtp_system rtp_system_descr; do
    rtp_systems+=("$rtp_system")
    rtp_system_description[$rtp_system]=$rtp_system_descr
    rtp_def_loglevel[$rtp_system]=$(grep "^log-level-$rtp_system *=" /etc/rtpengine/rtpengine.conf | sed 's/^.*= *//')
    if [ -z "${rtp_def_loglevel[$rtp_system]}" ]; then
      if [ "$rtp_system" = "internals" ]; then
        rtp_def_loglevel[$rtp_system]=-1
      else
        rtp_def_loglevel[$rtp_system]=$(grep "^log-level *=" /etc/rtpengine/rtpengine.conf | sed 's/^.*= *//')
      fi
    fi
  done < <("${rtpengine_command[@]}" list loglevels)
fi

# ----- functions definition ----
usage() {
  echo "Usage: $0 <ngcp-component> <options>

Usage example: $0 all --get

  ngcp-component:
    lb              set/unset log level for lb log (default 1)
    proxy           set/unset log level for proxy log (default 1)
    sbc             set/unset log level for sbc (sems) log (default 2)
    rtpengine <sys> set/unset log level for rtpengine log (default varies)
    all             set/unset log level for all the components

  rtpengine logging systems:"
  for rtp_system in "${rtp_systems[@]}"; do
    printf '    %-15s %s\n' "$rtp_system" "${rtp_system_description[$rtp_system]}"
  done
  printf '    %-15s %s\n' all "Apply to all of the above"

  echo "
  options:
    --set-default|-sd   set default log level
    --set-verbose|-sv   increase log level to verbose (for troubleshooting purpose)
    --get|-g            get current log level value
    --disable|-d        set all loglevels to 0
"
}

get_action() {
  case "$PARAM" in
    --disable|-d)
      echo "Disabling log level for $COMPONENT..."
      set_level=true
      lb_opt=(lb fifo corex.debug 0)
      proxy_opt=(proxy fifo corex.debug 0)
      sbc_opt=(-c "set_loglevel 0")
      for rtp_system in "${rtp_systems[@]}"; do
        rtpengine_opt[$rtp_system]="set loglevel $rtp_system 0"
      done
      ;;
    --set-default|-sd)
      echo "Setting default level for $COMPONENT..."
      set_level=true
      lb_opt=(lb fifo corex.debug 1)
      proxy_opt=(proxy fifo corex.debug 1)
      sbc_opt=(-c "set_loglevel 2")
      for rtp_system in "${rtp_systems[@]}"; do
        rtpengine_opt[$rtp_system]="set loglevel $rtp_system ${rtp_def_loglevel[$rtp_system]}"
      done
      ;;
    --set-verbose|-sv)
      echo "Setting verbose level for $COMPONENT..."
      set_level=true
      lb_opt=(lb fifo corex.debug 2)
      proxy_opt=(proxy fifo corex.debug 2)
      sbc_opt=(-c "set_loglevel 3")
      for rtp_system in "${rtp_systems[@]}"; do
        rtpengine_opt[$rtp_system]="set loglevel $rtp_system 7}"
      done
      ;;
    --get|-g)
      set_level=false
      lb_opt=(lb fifo corex.debug)
      proxy_opt=(proxy fifo corex.debug)
      sbc_opt=(-c "get_loglevel")
      for rtp_system in "${rtp_systems[@]}"; do
        rtpengine_opt[$rtp_system]="list loglevel $rtp_system"
      done
      ;;
    *)
      usage
      exit 1
      ;;
  esac
}
#---- end functions definition ----

case "$COMPONENT" in
  lb)
    if "${enable_lb}" ; then
      get_action
      if $set_level ; then
        lb_level=$(ngcp-kamctl "${lb_opt[@]}" | jq '.new')
      else
        lb_level=$(ngcp-kamctl "${lb_opt[@]}" | jq '.debug')
      fi
    fi
    echo "${COMPONENT} loglevel is ${lb_level:-not available}."
    exit 0
    ;;
  proxy)
    if "${enable_proxy}" ; then
      get_action
      if $set_level ; then
        proxy_level=$(ngcp-kamctl "${proxy_opt[@]}" | jq '.new')
      else
        proxy_level=$(ngcp-kamctl "${proxy_opt[@]}" | jq '.debug')
      fi
    fi
    echo "${COMPONENT} loglevel is ${proxy_level:-not available}."
    exit 0
    ;;
  sbc)
    if "${enable_sbc}" ; then
      get_action
      sems_level=$("${sems_command[@]}" "${sbc_opt[@]}" | grep -E '^loglevel' | awk -F'[^0-9]*' '{print $2}')
    fi
    echo "${COMPONENT} loglevel is ${sems_level:-not available}."
    exit 0
    ;;
  rtpengine)
    if "${enable_rtp}" ; then
      get_action
      if [ "$RTPENGINE_SYS" = "all" ]; then
        for rtp_system in "${rtp_systems[@]}"; do
          rtp_level=$("${rtpengine_command[@]}" "${rtpengine_opt[$rtp_system]}" | sed 's/.*setting loglevel to //')
          echo "${COMPONENT} ${rtp_system} loglevel is ${rtp_level:-not available}."
        done
      else
        rtp_level=$("${rtpengine_command[@]}" "${rtpengine_opt[$RTPENGINE_SYS]}" | sed 's/.*setting loglevel to //')
        echo "${COMPONENT} ${RTPENGINE_SYS} loglevel is ${rtp_level:-not available}."
      fi
    else
      echo "${COMPONENT} loglevel is ${rtp_level:-not available}."
    fi
    exit 0
    ;;
  all)
    get_action
    # Get levels
    if $set_level ; then
      ${enable_lb} && lb_level=$(ngcp-kamctl "${lb_opt[@]}" | jq '.new')
      ${enable_proxy} && proxy_level=$(ngcp-kamctl "${proxy_opt[@]}" | jq '.new')
    else
      ${enable_lb} && lb_level=$(ngcp-kamctl "${lb_opt[@]}" | jq '.debug')
      ${enable_proxy} && proxy_level=$(ngcp-kamctl "${proxy_opt[@]}" | jq '.debug')
    fi
    ${enable_sbc} && sems_level=$("${sems_command[@]}" "${sbc_opt[@]}" | grep -E '^loglevel' | awk -F'[^0-9]*' '{print $2}')
    declare -A rtp_levels
    if "${enable_rtp}"; then
      for rtp_system in "${rtp_systems[@]}"; do
        rtp_levels[$rtp_system]=$("${rtpengine_command[@]}" "${rtpengine_opt[$rtp_system]}" | sed 's/.*setting loglevel to //')
      done
    fi
    ${enable_rtp} && rtp_level=$("${rtpengine_command[@]}" "${rtpengine_opt[@]}" | sed 's/.*setting loglevel to //')

    echo "lb loglevel is ${lb_level}."
    echo "proxy loglevel is ${proxy_level}."
    echo "sbc loglevel is ${sems_level}."
    for rtp_system in "${rtp_systems[@]}"; do
      echo "rtpengine ${rtp_system} loglevel is ${rtp_levels[$rtp_system]}."
    done
    exit 0
    ;;
  *)
    usage
    exit 1
esac
