#!/bin/bash

GDS_KAFKA_PATH=$(cd "$(dirname "$0")";pwd)
PROGNAME=gds-kafka
PROG=${GDS_KAFKA_PATH}/${PROGNAME}.jar
WATCHER=${GDS_KAFKA_PATH}/watcher.sh
stdoutlog=/dev/tty
CAT=`which cat`
SED=`which sed`
GREP=`which egrep`
VM_OPTIONS=""


usage() {
    echo "sh watcher.sh OPTION INSTANCEPATH"
    echo "  OPTION:"
    echo "      -s --silence: Redirect output to $GDS_KAFKA_PATH/watcher.log"
    echo "      -a --add: start the instance and add watcher"
    echo "      -d --del: stop the instance and delete the watcher"
    echo "      -m --monitor: watch once, start the instance if it is not working"
    echo "      -r --restart: restart the instance"
    echo "      -l --list: list instances"
    echo "      -e --environ: load environment to support encrypt/decrypt functions"
    echo "      -h --help: show usage"
    echo "  INSTANCEPATH: instance path"
}

printlog() {
    currTime=$(date)
    echo "${currTime} $1" >> ${stdoutlog}
}

# 0 means instance is dead; 1 means instance is alive
isInstanceAlive() {
    result=$(ps -ef | grep java | grep ${PROGNAME} | grep -w ${INSPATH} | wc -l)
    if [ X"$result" == X"0" ]; then
        return 0
    else
        return 1
    fi
}

startInstance() {
    confpath=${INSPATH}"/GDS-Kafka.properties"

    isInstanceAlive
    if [ X"$?" == X"1" ] ; then
        PID=$(ps -ef | grep java | grep ${PROGNAME} | grep -w ${INSPATH} | awk '{print $2}')
        echo "$(date) Instance is already running:" ${INSPATH} "PID:" ${PID} >> ${stdoutlog}
        return 1
    fi

    VM_OPTIONS_FILE="${INSPATH}/gds-kafka.vmoptions"
    if [ -r "$VM_OPTIONS_FILE" ]; then
      VM_OPTIONS=`"$CAT" "$VM_OPTIONS_FILE" | "$GREP" -v "^#.*"`
    fi

    java -Dscc.conf=${GDS_KAFKA_PATH}/config/scc.conf ${VM_OPTIONS} -jar ${PROG} -INSTANCEPATH ${INSPATH} 1>/dev/null 2>&1 &

    sleep 1

    isInstanceAlive
    if [ X"$?" == X"1" ] ; then
        PID=$(ps -ef | grep java | grep ${PROGNAME} | grep -w ${INSPATH} | awk '{print $2}')
        printlog "Start the instance: "${INSPATH}" PID: "${PID}
        return 0
    else
        printlog "Cannot start the instance: "${INSPATH}" return code is: "${ret}
        return 1
    fi
}

stopInstance() {
    isInstanceAlive
    if [ X"$?" == X"1" ] ; then
        insPID=$(ps -ef | grep java | grep ${PROGNAME} | grep -w ${INSPATH} | awk '{print $2}')
        kill ${insPID}
        sleep 3
        isInstanceAlive
        if [ X"$?" == X"0" ] ; then
            printlog "Stop the instance: "${INSPATH}" PID: "${insPID}
        else
            printlog "Failed to stop the instance: "${INSPATH}" PID: "${insPID}
        fi
    else
        printlog "Instance is not running: "${INSPATH}
    fi
}

add2Crontab() {
    result=$(crontab -l | grep ${WATCHER} | grep -w ${INSPATH} | wc -l)
    if [ X"$result" == X"0" ] ; then
        (crontab -l; echo "* * * * * source /etc/profile;(if [ -f ~/.profile ];then source ~/.profile;fi);source ~/.bashrc;nohup ${WATCHER} -s -m ${INSPATH}") | crontab
        printlog "Add instance watcher on "${INSPATH}
    else
        printlog "Instance is already been watched: "${INSPATH}
    fi
}

delCrontab() {
    (crontab -l | grep -w -v ${INSPATH}) | crontab
    printlog "Delete instance watcher from "${INSPATH}
}

addWatcher() {
    startInstance
    if [ X"$?" == X"0" ]; then
        add2Crontab
    fi
}

delWatcher() {
    stopInstance
    delCrontab
}

startWatcher() {
    isInstanceAlive
    result=$?
    if [ X"$result" == X"0" ]; then
        printlog "[WARN] Instance "${INSPATH}" is missing, try to restart it."
        startInstance
    else
        PID=$(ps -ef | grep java | grep ${PROGNAME} | grep -w ${INSPATH} | awk '{print $2}')
        printlog "Instance ${INSPATH} is alive "$result" PID: "${PID}
    fi
}

listWatcher() {
    date
    echo "Now below instances are watched:"
    insArr=$(crontab -l |grep ${WATCHER} | awk -F ' -m ' '{print $2}' | awk '{print $1}')
    for ins in ${insArr[@]};
    do
        PID=$(ps -ef | grep java | grep ${PROGNAME} | grep -w ${ins} | awk '{print $2}')
        echo ${PID} ${ins}
    done
}

ARGS=`getopt -a -o sa:d:m:r:leh -l silence,add:,delete:,monitor:,restart:,list,encryptString,help -- "$@"`

eval set -- "${ARGS}"

while true
do
    case "$1" in
        -s|--silence)
            stdoutlog=/dev/null
            ;;
        -a|--add)
            INSPATH=$(realpath $2)
            if [ X${ACTION} == X"" ] ; then
                ACTION="ADD"
            else
                echo "Conflict options."
                exit
            fi
            shift
            ;;
        -d|--delete)
            INSPATH=$(realpath $2)
            if [ X${ACTION} == X"" ] ; then
                ACTION="DELETE"
            else
                echo "Conflict options."
                exit
            fi
            shift
            ;;
        -m|--monitor)
            INSPATH=$(realpath $2)
            if [ X${ACTION} == X"" ] ; then
                ACTION="MONITOR"
            else
                echo "Conflict options."
                exit
            fi
            shift
            ;;
        -r|--restart)
            INSPATH=$(realpath $2)
            if [ X${ACTION} == X"" ] ; then
                ACTION="RESTART"
            else
                echo "Conflict options."
                exit
            fi
            shift
            ;;
        -l|--list)
            if [ X${ACTION} == X"" ] ; then
                ACTION="LIST"
            else
                echo "Conflict options."
                exit
            fi
            ;;
        -h|--help)
            usage
            shift
            break
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "$1 is not an option!"
            usage
            exit
            ;;
    esac
    shift
done

case "$ACTION" in
    "ADD")
        addWatcher
        ;;
    "DELETE")
        delWatcher
        ;;
    "LIST")
        listWatcher
        ;;
    "MONITOR")
        startWatcher
        ;;
    "RESTART")
        stopInstance
        startInstance
        ;;
esac