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

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

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"

# 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
}

# 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
}

# 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 60 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
    fi
    echo "Stopping CM:"
    pkill -f $KILL_RDR 
    abort_after_timeout 60
}

# 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=60
    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
}

# 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
    
        $JAVA -server -Xconcurrentio -DAPP=CM -DconfigFile=cm.conf -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 
