#!/usr/bin/env bash
#
# Startup script for the Cisco Collection Manager
#

. ~scmscm/setup/common.sh || {
    echo "error - cannot find common definitions - exiting"
    exit 1
}

. ~scmscm/scripts/common.sh || {
    echo "error - cannot find common definitions - exiting"
    exit 1
}

export CONN_PROP_DIR=com/cisco/scmscm/db
export CONN_PROP_FILE=insightdb.properties
export MYSQL_EDITION_FILE=mysql-version.txt

which zip unzip &> /dev/null
if [[ "$?" == "0" ]]; then

ta_gracefull_stop=$(getValue ~scmscm/cm/config/taadapter.conf agg_cm_stop )
rag_gracefull_stop=$(getValue ~scmscm/cm/config/ragadapter.conf agg_cm_stop )
custom_gracefull_stop=$(getValue ~scmscm/cm/config/customadapter.conf agg_cm_stop )

if [ "$CM_HOME" ]; then
        # override the location of ~pcube for locations
        HOME_FLAG="-Dcom.cisco.scmscm=$CM_HOME"
        PQBHOME=$CM_HOME
else
        HOME_FLAG=$(printf ' -Dcom.cisco.scmscm.home=%s' ~scmscm)
        PQBHOME=~scmscm
fi


export LANG=en_US

export CM_PATH=${PQBHOME}/cm/bin
export CM_LIB=${PQBHOME}/cm/lib
export CONFIG_PATH=${PQBHOME}/cm/config
export UM_PATH=${PQBHOME}/cm/um

export UMLIBS=$UM_PATH/um_core.jar:$UM_PATH/jdmkrt.jar:$UM_PATH/xerces.jar:$UM_PATH/antlr2.7.1.jar:$UM_PATH/regexp.jar

export CMLIBS=$CM_LIB/commons-beanutils.jar:$CM_LIB/commons-collections-3.2.1.jar:$CM_LIB/commons-digester-2.0.jar:$CM_LIB/commons-lang-2.4.jar:$CM_LIB/commons-logging.jar:$CM_LIB/velocity-dep-1.3.1.jar:$CM_LIB/commons-httpclient-2.0.1.jar:$CM_LIB/commons-validator-1.3.1.jar:$CM_LIB/jep-2.4.1.jar
export LOG4J=$CM_LIB/log4j.jar

export CLASSPATH=$CM_PATH/cm.jar:$CMLIBS:$UM_PATH/um_core.jar:$LOG4J

KILL_RDR="APP=CM"
KILL_RDR_CHILD="configFile=cm"
CM_CONF_FILE=${CONFIG_PATH}/cm.conf
CUSTOM_CONF_FILE=${CONFIG_PATH}/customadapter.conf
CUSTOM_ADP_ENABLED=$(getValue ~scmscm/cm/config/cm.conf "adapter.5")
RAG_ADP_ENABLED=$(getValue ~scmscm/cm/config/cm.conf "adapter.4")
TA_ADP_ENABLED=$(getValue ~scmscm/cm/config/cm.conf "adapter.3")
OSFP_ENABLED=$(getValue ~scmscm/cm/config/customadapter.conf "active")
OS_ENABLED=$(getValue ~scmscm/cm/config/customadapter.conf "active")
DEVICE_COUNT_ENABLED=$(getValue ~scmscm/cm/config/ragadapter.conf "device_counting")
VIDEO_MONITOR_ENABLED=$(getValue ~scmscm/cm/config/ragadapter.conf "enable_video_monitor")
VIDEO_QOE_ENABLED=$(getValue ~scmscm/cm/config/ragadapter.conf "enable_video_qoe")

# prevent the script from being run as root:
if [ -w /etc/passwd ]; then echo "This script cannot be run by root"; exit 1; fi

JAVA="$PQBHOME/cm/lib/java/bin/java"

# is the CM or adapters running now?
is_cm_up () {
    [[ "$(pgrep -f $KILL_RDR)" || "$(pgrep -f $KILL_RDR_CHILD)" ]] &> /dev/null
}

is_main_up () {
[[ "$(pgrep -f $KILL_RDR)" ]] &> /dev/null
}

is_adapter_up () {
[[ "$(pgrep -f $1)" ]] &> /dev/null
}

# check for the CM Mail process every 1 sec and wait for gracefull shutdown
# It will show processing status every 1 sec
stop_without_timeout () { 
 local spinstr='|/-\'
 while is_main_up && is_adapter_up $1 ; do
        local temp=${spinstr#?}
        printf " (%c)  " "$spinstr"
        local spinstr=$temp${spinstr%"$temp"}
        sleep 1
        printf "\b\b\b\b\b\b"
  done
}

# check for maximum $1 seconds (one every second)
# if the CM is still up.  If after $1 seconds it's still
# there (persumably hung) - abort it.
abort_after_timeout () {
    timeout=$1
    while [ $timeout -gt 0 ] && is_cm_up; do
        sleep 1
        let timeout=timeout-1
    done
    is_cm_up && abort_cm
}

#Load Array with gracefull stop Enabled Adapters 
load_array_of_enabled_adapters () {
        if [[ $CUSTOM_ADP_ENABLED == "com.cisco.scmscm.adapters.custom.CustomAdapter" ]] && [[ $custom_gracefull_stop == "true" ]]; then
        array[0]="CustomAdapter"
        fi
        
        if [[ $TA_ADP_ENABLED == "com.cisco.scmscm.adapters.topper.TAAdapter" ]] && [[ $ta_gracefull_stop == "true" ]]; then
        array[1]="TAAdapter"
        fi
        
        if [[ $RAG_ADP_ENABLED == "com.cisco.scmscm.adapters.rag.RAGAdapter" ]] && [[ $rag_gracefull_stop == "true" ]]; then
        array[2]="RAGAdapter"
        fi
        
        return `echo ${#array[@]}`      
}

# stop the cm gracefully with a SIGINT   
# we send the signal just to the main cm process, it will take
# care by itself to kill the adapter processes.
# if after 90 seconds there are still CM processes, we abort them.
stop_cm() {
    if [[ $1 == "" ]]; then
        yesorno "This will stop all running  CM processes. Are you sure you want to continue?"

        if [ $? -ne 0 ]; then
          exit 0
        fi
    elif [[ $1 == "force" ]]; then
        echo "Stopping CM:"
        pkill -f $KILL_RDR 
        abort_after_timeout 90
        exit
    fi
            
    echo "Stopping CM:"
    pkill -f $KILL_RDR
    
    	  load_array_of_enabled_adapters
        if [ $? -ne 0 ]; then
            for i in "${array[@]}"
            do
            #echo -e "This may take some time to finish off $i aggregation process (To Fetch Top Reports, For DB insertion & CSV save functionality ) smoothly\n"
            echo -e "This may take some time to finish off $i aggregation process\n"
            echo -n "Stopping $i Process"
            	  stop_without_timeout $i 
            	  echo -e "\n"
            done
            sleep 5
            abort_cm
        else 
        abort_after_timeout 90
        fi
echo -e "\nStopped CM"        
}

# stop the cm forcefully
abort_cm() {
    pkill -9 -f $KILL_RDR &> /dev/null
    pkill -9 -f $KILL_RDR_CHILD &> /dev/null
}

is_process_up () {
    [[ "$(pgrep -f $1)" ]] &> /dev/null
}

stop_process () {
    pkill -f $1

	timeout=90
    while [ $timeout -gt 0 ] && is_process_up $1; do
        sleep 1
        let timeout=timeout-1
    done
    is_process_up $1 && abort_process $1
    is_process_up $KILL_RDR_CHILD && abort_process $KILL_RDR_CHILD
}

abort_process () {
    pkill -9 -f $1 &> /dev/null
}

get_table_list () {
TMPFILE="/tmp/dbtable-$$"
all_tables > ${TMPFILE}
}

table_exist () {
              cat $TMPFILE | grep -i $1 > /dev/null
              if [ $? -ne 0 ]; then
                echo 0;
              else
                echo 1;
              fi
}
# start the cm
start_cm() {
        if is_process_up $KILL_RDR; then
             echo "error - CM already running"
             return 1
        fi
        echo "Starting CM..."
        ~scmscm/cm/bin/load_devicetype.sh > /dev/null 2>&1         
       is_db_up
       if [ $? -eq 0 ]; then
             get_table_list       
             vsaType=$(getValue ~scmscm/cm/config/ragadapter.conf vsa_type)         
             if [[ $RAG_ADP_ENABLED == "com.cisco.scmscm.adapters.rag.RAGAdapter" ]] ; then
                      

                      if [[ $DEVICE_COUNT_ENABLED == "true" ]] && [[ $(table_exist DEVICE_TYPES) -eq 0 ]] ; then
                      ~scmscm/scripts/device_count_ini.sh --update > /dev/null 2>&1
                      fi

                      if [[ $VIDEO_MONITOR_ENABLED == "true" ]] && [[ $(table_exist VIDEO_MONITOR_TYPES) -eq 0 ]] ; then
                      ~scmscm/scripts/update_videotypes.sh --update > /dev/null 2>&1
                      fi
             fi
             if [[ $CUSTOM_ADP_ENABLED == "com.cisco.scmscm.adapters.custom.CustomAdapter" ]] ; then
                      if [[ $OSFP_ENABLED == "true" ]] && [[ $(table_exist OSFP_TYPES) -eq 0 ]] ; then
                      ~scmscm/scripts/update_osfptypes.sh --update > /dev/null 2>&1
                      fi
             fi
             if [[ $CUSTOM_ADP_ENABLED == "com.cisco.scmscm.adapters.custom.CustomAdapter" ]] ; then
                      if [[ $OS_ENABLED == "true" ]] && [[ $(table_exist OS_TYPES) -eq 0 ]] ; then
                      ~scmscm/scripts/update_ostypes.sh --update > /dev/null 2>&1
                      fi
             fi
             rm -f ${TMPFILE}
      fi
            $JAVA -server -Xconcurrentio -DAPP=CM -DconfigFile=cm.conf  -Djava.security.egd=file:/dev/./urandom -Dcom.cisco.scmscm.configPath=$CONFIG_PATH $HOME_FLAG \
               -Dcom.pcube.agent.cfg.file=p3cm.cfg -Dcom.pcube.filemanager.defaultPath=$UM_PATH -cp \
               $CLASSPATH com.cisco.scmscm.CM \
               2>&1 |logger -t CM -p daemon.notice &
}

# invoke some CM class directly from the command line with args.
# example: ~/cm/bin/cm invoke com.cisco.scmscm.adapters.jdbc.JDBCAdapter   -executeQuery '$dbinfo.sql.dbtables'
invoke () {
        if [ -z "$APP" ]
        then
          APP="invoke"
        fi
        $JAVA -DAPP=$APP  -Dcom.cisco.scmscm.configPath=$CONFIG_PATH $HOME_FLAG \
         -Dcom.pcube.agent.cfg.file=p3cm.cfg -Dcom.pcube.filemanager.defaultPath=$UM_PATH -cp "$CLASSPATH" "$@"
}

restart () {
  stop_process $KILL_RDR
  start_cm
}

# remove the state files left by the EM agent
# this is not used any more by the EM agent; retained for back compat.
del_states() {
        if [ -f $UM_PATH/flsuhtodefaults.tmp ]; then
                echo "Deleting EM states (flush to defaults)"
                rm -rf $UM_PATH/states/*
                rm -f $UM_PATH/flsuhtodefaults.tmp
        fi
}


case "$1" in
  version)
    cat ~scmscm/.cm_cd_version
    ;;
  dbversion)
        echo "CM database:"
        . ~scmscm/setup/common.sh
          
          db_version
          
    ;;
  start)
       
       start_cm
       
    ;;
  stop)
    stop_cm
    ;;
  stop_f)
    # Hidden force option for regression test setup
    stop_cm force
    ;;
  abort)
    echo "Aborting CM: "
    abort_cm
    ;;  
  invoke)
    shift
    invoke "$@"
    exit $?
    ;;
  restart)
    # start_cm stops the previous one already, just
    # make sure we do it in the background in case this is
    # invoked from within the UM agent.
    
    restart
  
    ;;
  restart_del_states)
    (stop_cm ; sleep 30 ; abort_cm ; sleep 1 ; del_states ; start_cm) &
    ;;
  *)
    echo "Usage: $0 {version|dbversion|start|stop|abort|restart|invoke CLASS ARGS}"
    exit 1
    ;;
esac
 
exit 0 
  else
 echo "ERROR:ZIP/UNZIP utility is not found.make sure that you have these utilities for Fresh Installation/Upgrade to happen successfully"
 fi