#!/bin/sh
#-------------------------------------------------------------------------------
# charon_menu_logchk
#-------------------------------------------------------------------------------
# Copyright (C) 2013-2022 STROMASYS.
# All rights reserved.
#
#set -x
VERSION=2.8

. `dirname $0`/charon_common
. `dirname $0`/charon_common_menu

LOGFLIST="${CHARONDIR}/utils/charon_logchk.list"
BOOTLIST="${CHARONDIR}/utils/charon_gstart.boot"
LESSWARNONREMOVAL="/root/.charon.less.warn.on.dongle.removal"
DISABLEMONUSBALRT="/root/.charon.disable.monusb.immediate.alert"

SVCNAME="charon_logchk"
MONLOG="${CHARONDIR}/log/charon_logchk.log"
TAILCMD=`grep ^TAILCMD= ${CHARONDIR}/utils/charon_logchk 2>/dev/null | cut -f2 -d'=' | tr -d '"'`

get_preferences

function display_hr
{
  if test "${SEMIGRAPH}" = "enabled"
  then
    tput smacs
    echo "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
    tput rmacs
  else
    echo "--------------------------------------------------------------------------------"
  fi
}

function display_logsmonitored
{
  typeset -i I=0
  echo
  tput bold
  echo "${FGBLUE}$1[0m"
  tput sgr0
  display_hr
  touch ${LOGFLIST}
  if test `cat ${LOGFLIST} | wc -l` -eq 0
  then
    test "${GLOBALLOGMON}" = "enabled" && echo "None."
  else
    cat ${LOGFLIST} | while read RLOGF
    do
      if test "$2" = "-num"
      then
        I=I+1
        printf "%2d" ${I}
        echo -n " - "
      fi

      echo -n "${RLOGF}, "
      if test -e ${RLOGF}
      then
        if test -s ${BOOTLIST}
        then
          grep -v ^# ${BOOTLIST} | while read LINE
          do
            EMU=`echo ${LINE} | cut -f1 -d';'`
            CFG=`echo ${LINE} | cut -f2 -d';'`
            get_logfile ${CFG}
            if test "${LOGF}" = "${RLOGF}"
            then
              CFGBAS=`basename ${CFG}|sed "s=\.cfg==g"`
              if test -s /etc/systemd/system/charon_logmon_${CFGBAS}.service
              then
                SVCCHK=`systemctl is-enabled charon_logmon_${CFGBAS}.service 2>/dev/null`
                test "${SVCCHK}" = "enabled" && echo -n "[32m" || echo -n "[31m"
                echo -n "${SVCCHK}[0m, "
                SVCCHK=`systemctl is-active charon_logmon_${CFGBAS}.service 2>/dev/null`
                if test "${SVCCHK}" = "active"
                then
                  PRC=`ps -ef | grep "${TAILCMD} ${RLOGF}$" | grep -v grep`
                  if test -n "${PRC}"
                  then
                    echo -n "[32mrunning[0m"
                  else
                    echo -n "[35mstarting[0m"
                  fi
                else
                  if test "${GLOBALLOGMON}" = "enabled"
                  then
                    echo -n "[31m${SVCCHK}[0m"
                  else
                    echo -n "[36m${SVCCHK}[0m"
                  fi
                fi
              else
                if test "${GLOBALLOGMON}" = "enabled"
                then
                  echo -n "[31mnot installed[0m"
                else
                  echo -n "[36mnot installed[0m"
                fi
              fi
            fi
          done
        else
          echo -n "not associated to guest"
        fi
        echo -n ", last modified on "
        ls -l ${RLOGF} | awk '{print $6,$7,$8,$9,$10,$11}'|sed -e "s=${RLOGF}==g" -e "s=->=\n  [36mRotating log file[0m /=g"
      else
        echo "log file not found"
        #touch ${RLOGF}
      fi
    done
  fi
  if test -s ${BOOTLIST}
  then
    grep -v ^# ${BOOTLIST} | while read LINE
    do
      EMU=`echo ${LINE} | cut -f1 -d';'`
      CFG=`echo ${LINE} | cut -f2 -d';'`
      get_logfile ${CFG}
      if test -z "`grep ^${LOGF}$ ${LOGFLIST}`"
      then
        if test "${GLOBALLOGMON}" = "enabled"
        then
          echo "[1m[31mLog ${LOGF} (`basename ${EMU}`) is not monitored![0m Please update the list"
        else
          echo "- `basename ${EMU}` - ${LOGF}"
        fi
      fi
    done
  fi
}

function manage_systemd_service
{
  # $1 = create, delete, start, stop, is-active
  # $2 = log name full path
  if test -s ${BOOTLIST}
  then
    rm -f /tmp/charon_menu_logchk.cfgbas.tmp 2>/dev/null
    grep -v ^# ${BOOTLIST} | while read LINE
    do
      EMU=`echo ${LINE} | cut -f1 -d';'`
      CFG=`echo ${LINE} | cut -f2 -d';'`
      get_logfile ${CFG}
      test "${LOGF}" = "$2" && basename ${CFG} | sed "s=\.cfg==g" >/tmp/charon_menu_logchk.cfgbas.tmp
    done
    CFGBAS=`cat /tmp/charon_menu_logchk.cfgbas.tmp 2>/dev/null`
    if test -n "${CFGBAS}"
    then
      case "$1"
      in
        "create")
          echo
          if test ! -s /etc/systemd/system/charon_logmon_${CFGBAS}.service
          then
            #--- Virtual machine log monitoring service creation
            SVC_DESCRI="CHARON log monitoring `basename ${EMU}`/${CFGBAS}"
            SVC_BEFORE="charon_${CFGBAS}"
            SVC_WORKDI=`dirname $2`
            SVC_LOGFIL=$2
            cat ${CHARONDIR}/utils/templates/charon_logmon_VIRTUALMACHINE.service | \
                sed -e "s=<SVC_DESCRI>=${SVC_DESCRI}=g" \
                    -e "s=<SVC_BEFORE>=${SVC_BEFORE}=g" \
                    -e "s=<SVC_WORKDI>=${SVC_WORKDI}=g" \
                    -e "s=<SVC_LOGFIL>=${SVC_LOGFIL}=g" \
                       >/etc/systemd/system/charon_logmon_${CFGBAS}.service
            systemctl daemon-reload
          fi

          SVCCHK=`systemctl is-enabled charon_logmon_${CFGBAS}.service 2>/dev/null`
          if test "${SVCCHK}" != "enabled"
          then
            systemctl enable charon_logmon_${CFGBAS}.service 2>/dev/null
            if test $? = 0
            then
              echo "Service charon_logmon_${CFGBAS}.service is enabled."
            else
              echo "[1mFailed to enable service charon_logmon_${CFGBAS}.service. Please check manually.[0m"
            fi
          fi
          ;;
        "start")
          echo
          systemctl reset-failed charon_logmon_${CFGBAS}.service
          systemctl start        charon_logmon_${CFGBAS}.service
          ;;
        "stop")
          echo
          systemctl stop         charon_logmon_${CFGBAS}.service
          ;;
        "delete")
          echo
          systemctl disable      charon_logmon_${CFGBAS}.service
          rm -f /etc/systemd/system/charon_logmon_${CFGBAS}.service
          systemctl daemon-reload
          ;;
        "is-active")
          systemctl is-active charon_logmon_${CFGBAS}.service 2>/dev/null
          ;;
      esac
    else
      echo "[31mERROR:[0m Cannot $1 service. No managed guest associated with the log file"
      echo
      Press_Enter
    fi
  else
    echo "[31mERROR:[0m Cannot $1 service. No managed guest defined"
    echo
    Press_Enter
  fi
}

while test 1
do
  display_header "Manage monitored guests logs"
  echo
  if test `id -u` -ne 0
  then
    tput bold
    echo "Must be root !"
    tput sgr0
    Press_Enter
    echo
    exit 1
  fi
  if test "${GLOBALLOGMON}" != "enabled"
  then
    echo "[46m[30m WARNING [0m Charon log monitoring (global) has been DISABLED."
  fi

  if test "${GLOBALLOGMON}" = "enabled"
  then
    tput bold
    echo "${FGBLUE}Service status[0m"
    tput sgr0
    display_hr
  fi
  SVCTOP=""
  SVCMSG="Manage 'systemd' services"
  if test "${GLOBALLOGMON}" = "enabled"
  then
    if test ! -s /etc/systemd/system/charon_monusb.service
    then
      echo "Installing aksusbd monitoring service..."
      cp -f ${CHARONDIR}/utils/templates/charon_monusb.service /etc/systemd/system/charon_monusb.service
      systemctl daemon-reload
      systemctl enable charon_monusb.service
      systemctl start  charon_monusb.service
      sleep 3
    fi
    echo -n "aksusbd monitoring service is "
    SVCCHK=`systemctl is-enabled charon_monusb.service 2>/dev/null`
    test "${SVCCHK}" = "enabled" && echo -n "[32m" || echo -n "[31m"
    echo -n "${SVCCHK}[0m, "
    SVCCHK=`systemctl is-active charon_monusb.service 2>/dev/null`
    if test "${SVCCHK}" = "active"
    then
      PRC=`systemctl show -p ExecMainPID charon_monusb 2>/dev/null | cut -f2 -d'='`
      if test -n "`ps --ppid ${PRC} | grep journalctl`"
      then
        echo "[32mrunning[0m"
      else
        echo "[35mstarting[0m"
      fi
    else
      echo "[31m${SVCCHK}[0m"
    fi
  fi
  if test "${GLOBALLOGMON}" = "enabled"
  then
    OPTBOLD="[1m"
    test -e ${DISABLEMONUSBALRT} && echo "Monitoring in silent mode due to alerts management settings"
  else
    OPTBOLD="[90m"
  fi

  display_logsmonitored "Logs checked / Monitoring status"

  echo
  tput bold
  echo "${FGBLUE}Available options[0m"
  tput sgr0
  display_hr
  cat <<EOF
${OPTBOLD}1[0m - Update log files list              ${OPTBOLD}5[0m - ${SVCTOP}${SVCMSG}[0m
${OPTBOLD}2[0m - Start/stop monitoring log file     ${OPTBOLD}6[0m - Start or Restart aksusbd log monitor
[1m3[0m - View guest log files               [1m7[0m - Send/mail configuration and log files
${OPTBOLD}4[0m - View monitoring log file           ${OPTBOLD}8[0m - Restart all log monitoring services

EOF
  printf "${FGBLUE}Enter your choice (enter to refresh, 'q' to quit):[0m "
  read CH
  echo
  case "${CH}"
  in
    1)
      #---------------------------------------------------
      # Edit log files list
      #---------------------------------------------------
      if test "${GLOBALLOGMON}" = "enabled"
      then
        touch ${LOGFLIST}
        echo
        echo "[44m[37m Current log files list [0m"
        cat ${LOGFLIST}
        grep -v ^# ${BOOTLIST} | while read LINE
        do
          EMU=`echo ${LINE} | cut -f1 -d';'`
          CFG=`echo ${LINE} | cut -f2 -d';'`
          get_logfile ${CFG}
          RLOGF=${LOGF}
          if test -z "`grep ^${RLOGF}$ ${LOGFLIST}`"
          then
            echo "${FGBLUE}${LOGF} (`basename ${EMU}`) found and added.[0m"
            echo ${LOGF} >>${LOGFLIST}
            manage_systemd_service create ${LOGF}
          fi
        done
        echo

        cp -f ${LOGFLIST} /tmp/`basename ${LOGFLIST}`.before_edit

        while test 1
        do
          printf "Do you want to edit the log files list (y/n) ? "
          read ANS      
          case "${ANS}"
          in
            y)
              cat <<EOF
You will be editing the log file list.

Please respect the following:
- one log file per line
- log file with full path
- no blank line
- there is no file name check so ensure you enter the correct file name
EOF

              ask_editor noquit
              if test -n "${EDI}"
              then
                while test 1
                do
                  echo
                  echo "Updating file using '`basename ${EDI}`'..."
                  ${EDI} ${LOGFLIST} 2>/dev/null
                  grep -v ^$ ${LOGFLIST} >${LOGFLIST}.noemptylines
                  mv -f ${LOGFLIST}.noemptylines ${LOGFLIST}
                  if test -s ${LOGFLIST}
                  then
                    tput bold
                    echo "${FGBLUE}Log file list[0m"
                    tput sgr0
                    display_hr
                    cat ${LOGFLIST}
                    display_hr
                  else
                    echo "Log file list is empty !"
                  fi
                  while test 1
                  do
                    echo
                    tput bold
                    printf "Do you want to edit the file again (y/n) ? "
                    tput sgr0
                    read ANS
                    case "${ANS}"
                    in
                      y)
                        break 1
                        ;;
                      n)
                        diff /tmp/`basename ${LOGFLIST}`.before_edit ${LOGFLIST} | grep "^<" | awk '{print $2}' | while read RLOGF
                        do                      
                          manage_systemd_service stop   ${RLOGF}
                          manage_systemd_service delete ${RLOGF}
                        done
                        break 2
                        ;;
                      *)
                        tput cuu1;tput el
                        ;;
                    esac
                  done
                done
              fi
              break
              ;;
            n)
              break
              ;;
            *)
              tput cuu1;tput el
              ;;
          esac
        done
      fi
      ;;
    2)
      #---------------------------------------------------
      # Start/stop monitoring log file
      #---------------------------------------------------
      if test "${GLOBALLOGMON}" = "enabled"
      then
        while test 1
        do
          display_guestslist
          echo
          tput bold
          display_logsmonitored "Log files monitored" -num
          echo
          NLOGS=`grep -v ^# ${LOGFLIST} | wc -l`
          if test ${NLOGS:-0} -eq 1
          then 
            ANS=1
          else
            tput bold
            printf "Enter the log file number you want to start/stop (q to quit): "
            tput sgr0
            read ANS
            test "${ANS}" = "q" && break
          fi
          if test -n "${ANS}"
          then
            if test -z "`echo ${ANS} | tr -d [0123456789]`"
            then
              if test ${ANS} -lt 1 -o ${ANS} -gt `cat ${LOGFLIST} | wc -l`
              then
                echo "Incorrect value, out of range."
              else
                RLOGF=`head -${ANS} ${LOGFLIST} | tail -1`
                SVC_IS_ACTIVE=`manage_systemd_service is-active ${RLOGF} | cut -f1 -d'-' | tr [:lower:] [:upper:]`
                if test "${SVC_IS_ACTIVE}" = "DEACTIVATING"
                then
                  LOGACTION="stopping"
                  LOGACTDISP=""
                else
                  if test "${SVC_IS_ACTIVE}" = "ACTIVE"
                  then
                    LOGACTION="stop"
                    LOGACTDISP="[31mstop"
                  else
                    LOGACTION="start"
                    LOGACTDISP="[32mstart"
                  fi
                fi
                echo
                if test "${LOGACTION}" = "stop" -o "${LOGACTION}" = "start"
                then
                  while test 1
                  do
                    printf "Please confirm you want to `tput bold`${LOGACTDISP}`tput sgr0` (y/n): "
                    read ANS
                    case "${ANS}"
                    in
                      y)
                        manage_systemd_service ${LOGACTION} ${RLOGF}
                        if test ${NLOGS:-0} -eq 1
                        then
                          break 2
                        else
                          break
                        fi
                        ;;
                      n)
                        if test ${NLOGS:-0} -eq 1
                        then
                          break 2
                        else
                          break
                        fi
                        ;;
                      *)
                        tput cuu1;tput el
                        ;;
                    esac
                  done
                else
                  echo "[44m[37m Current state is starting, cannot start nor stop at the moment [0m"
                  echo
                fi
              fi
            else
              echo "Incorrect value."         
            fi
          fi
        done
      fi
      ;;
    3)
      #---------------------------------------------------
      # View guest log file
      #---------------------------------------------------
      while test 1
      do
        display_guestslist -num
        echo
        NLOGS=`grep -v ^# ${LOGFLIST} | wc -l`
        if test ${NLOGS:-0} -eq 1
        then 
          ANS=1
        else
          tput bold
          printf "Select the guest you want the log file to be viewed (q to quit): "
          tput sgr0
          read ANS
          test "${ANS}" = "q" && break
        fi

        if test -n "${ANS}"
        then
          if test -z "`echo ${ANS} | tr -d [0123456789]`"
          then
            if test ${ANS} -lt 1 -o ${ANS} -gt `grep -v ^# ${BOOTLIST} | wc -l`
            then
              tput bold
              echo "Incorrect value, out of range."
              tput sgr0
            else
              CFG=`grep -v ^# ${BOOTLIST} | head -${ANS} | tail -1 | cut -f2 -d';'`
              get_logfile ${CFG}
              if test -n "${LOGF}"
              then
                echo
                echo "Found definition of log file: ${LOGF}"
                echo
                select_logfile
              else
                tput bold
                echo "Log file name cannot be extracted from the configuration file."
                echo "Please check syntax."
                tput sgr0
              fi
            fi
            test ${NLOGS:-0} -eq 1 && break
          else
            tput bold
            echo "Incorrect value, must be numeric."
            tput sgr0
          fi
        fi
      done
      ;;
    4)
      #---------------------------------------------------
      # View monitoring log file
      #---------------------------------------------------
      if test "${GLOBALLOGMON}" = "enabled"
      then
        if test -s ${MONLOG}
        then
          ask_editor
          if test -n "${EDI}"
          then
            ${EDI} ${MONLOG} 2>/dev/null
          fi
        else
          echo "Log does not exist or is empty."
          sleep 1
        fi
      fi
      ;;
    5)
      touch ${LOGFLIST}
      if test "${GLOBALLOGMON}" = "enabled"
      then
        #---------------------------
        # Manage 'systemd' services
        #---------------------------
        while test 1
        do
          display_guestslist -num
          echo
          NGUESTS=`grep -v ^# ${BOOTLIST} | wc -l`
          if test ${NGUESTS:-0} -eq 0
          then 
            tput bold
            echo "Guests list is empty."
            tput sgr0
            break
          fi
          if test ${NGUESTS:-0} -eq 1
          then
            ANS=1
          else
            printf "Select the guest you want to see service state (q to quit, enter to refresh): "
            read ANS
            test "${ANS}" = "q" && break
          fi
          if test -n "${ANS}"
          then
            if test -z "`echo ${ANS} | tr -d [0123456789]`"
            then
              if test ${ANS} -lt 1 -o ${ANS} -gt ${NGUESTS:-0}
              then
                tput bold
                echo "Incorrect value, out of range."
                tput sgr0
              else
                GUEST_CFG=`grep -v ^# ${BOOTLIST} | head -${ANS} | tail -1 | cut -f2 -d';'`
                get_logfile ${GUEST_CFG}
                if test -n "${LOGF}"
                then
                  echo
                  GUEST_CFGBAS=`basename ${GUEST_CFG}|sed "s=\.cfg==g"`
                  while test 1
                  do
                    echo "[44m[37m charon_logmon_${GUEST_CFGBAS}.service status [0m"
                    systemctl -l status charon_logmon_${GUEST_CFGBAS}.service
                    echo
                    echo -n "Do you want to edit the .service file (y/n) ? "
                    read AN
                    case "${AN}"
                    in 
                      y)
                        ask_editor
                        if test -n "${EDI}"
                        then
                          ${EDI} /etc/systemd/system/charon_logmon_${GUEST_CFGBAS}.service 2>/dev/null
                          echo "Reloading systemd manager configuration..."
                          systemctl daemon-reload
                        fi
                        if test ${NGUESTS:-0} -eq 1
                        then
                          break 2
                        else
                          break
                        fi
                        ;;
                      n)
                        if test ${NGUESTS:-0} -eq 1
                        then
                          break 2
                        else
                          break
                        fi
                        ;;
                      *)
                        tput cuu1;tput el
                        ;;
                    esac
                  done
                else
                  tput bold
                  echo "Log file name cannot be extracted from the configuration file."
                  echo "Please check syntax."
                  tput sgr0
                fi
              fi
            else
              tput bold
              echo "Incorrect value, must be numeric."
              tput sgr0
            fi
          fi
        done
        echo
      fi
      ;;
    6)
      if test "${GLOBALLOGMON}" = "enabled"
      then
        echo
        echo "Restarting aksusbd log monitor service..."
        systemctl restart charon_monusb.service
        Press_Enter
      fi
      ;;
    7)
      ${CHARONDIR}/utils/charon_menu_sendlogs
      ;;
    8)
      if test "${GLOBALLOGMON}" = "enabled"
      then
        cat ${LOGFLIST} | while read RLOGF
        do
          echo
          SVC_IS_ACTIVE=`manage_systemd_service is-active ${RLOGF} | cut -f1 -d'-' | tr [:lower:] [:upper:]`
          if test "${SVC_IS_ACTIVE}" = "ACTIVE"
          then
            echo "Stopping log monitoring service for ${RLOGF}"
            manage_systemd_service stop ${RLOGF}
            sleep 1
            echo "Starting log monitoring service for ${RLOGF}"
            manage_systemd_service start ${RLOGF}
          else
            echo "Log monitoring service for ${RLOGF} is not running. Skipped."
          fi
        done
        Press_Enter
      fi
      ;;
    q)
      break
      ;;
    *)
      tput bel
      ;;
  esac
done

exit
