#!/bin/bash

readonly PATH='/usr/sbin:/usr/bin:/sbin:/bin'
cd "`dirname $0`" || exit 1

readonly SLEEP='sleep'

readonly G_SBIN_DIR=`pwd`
readonly G_PROC_NAME='bcm-agent'
readonly G_II_NAME='bcm-ii'
readonly G_SI_NAME='bcm-si'
readonly G_SUPERVISE_NAME='supervise.bcm-agent'
readonly PORT=781
readonly LOG_DIR='../log'
readonly TOKEN_FILE='../conf/agent.config'

check_port_using_dev_tcp()
{
    (echo > /dev/tcp/127.0.0.1/$1) >/dev/null 2>&1
    return $?
}

if [ "$PORT_CHECKER" = "" ]; then
    if type -p nc >/dev/null 2>&1; then
        PORT_CHECKER="nc -z 127.0.0.1"
    else
        PORT_CHECKER="check_port_using_dev_tcp"
    fi
fi

check()
{
    ps -eo pid,command | sed -ne "s/^ *//p" | sed -ne "1d; s/\(\d*\) \[\?\([^-][^] ]*\).*$/\1 \2/p" |sed -ne "s/\(\d*\) .*\/\(.*\)/\1 \2/p"|grep -E "\b${G_PROC_NAME}$" >& /dev/null
    return $?
}

help()
{
    echo "${0} <start|stop|restart|shutdown|reload|status>"
    exit 1
}

die()
{
    echo "[FAILED] ${1}"
    exit 1
}

ok()
{
    echo "[OK] ${1}"
}

check_port(){
    $PORT_CHECKER $1
    if [[ $? -eq 0 ]];then
        return 0
    else
        return 1
    fi  
}

signal()
{
    #kill supervise
    pkill -9 -f ${G_SUPERVISE_NAME}

    #kill bcm-agent
    all_possible_id=$(ps -eo pid,command | sed -ne "s/^ *//p" | sed -ne "1d; s/\(\d*\) \[\?\([^-][^] ]*\).*$/\1 \2/p" |sed -ne "s/\(\d*\) .*\/\(.*\)/\1 \2/p"|grep -E "\b${G_PROC_NAME}$"|awk '{print $1}')
    for proc_id in $all_possible_id
    do
        kill -9 ${proc_id}
        if [ $? -ne 0 ];then
            echo "[FAILED] kill ${proc_id} error"
        fi
    done

    #kill bcm-ii
    all_possible_id=$(ps -eo pid,command | sed -ne "s/^ *//p" | sed -ne "1d; s/\(\d*\) \[\?\([^-][^] ]*\).*$/\1 \2/p" |sed -ne "s/\(\d*\) .*\/\(.*\)/\1 \2/p"|grep -E "\b${G_II_NAME}$"|awk '{print $1}')
    for proc_id in $all_possible_id
    do
        kill -9 ${proc_id}
        if [ $? -ne 0 ];then
            echo "[FAILED] kill ${proc_id} error"
        fi
    done

    #kill bcm-si
    all_possible_id=$(ps -eo pid,command | sed -ne "s/^ *//p" | sed -ne "1d; s/\(\d*\) \[\?\([^-][^] ]*\).*$/\1 \2/p" |sed -ne "s/\(\d*\) .*\/\(.*\)/\1 \2/p"|grep -E "\b${G_SI_NAME}$"|awk '{print $1}')
    for proc_id in $all_possible_id
    do
        kill -9 ${proc_id}
        if [ $? -ne 0 ];then
            echo "[FAILED] kill ${proc_id} error"
        fi
    done
}

start()
{
    #if [[ $(ulimit -n) -lt 100000 ]];then
    #  die "fd limit less than 100000, start"
    #fi

    #if [ ! -f $TOKEN_FILE ]; then
    #    die "missing ../conf/agent.config"
    #fi

    mkdir -m 0777 -p $LOG_DIR

    check
    if [ $? -eq 0 ]; then
        ok "start"
        return 0
    fi

    for((i=0;i<10;i++)); do
        check_port $PORT
        if [ $? -eq 0 ]; then
            echo "port $PORT in use, pls check."
            sleep 1
        else
            break
        fi
    done

    check_port $PORT
    if [ $? -eq 0 ]; then
        echo "port $PORT in use, pls check."
        return 1
    fi

    #start program now
    pkill -9 -f ${G_SUPERVISE_NAME}
    ${SLEEP} 1
    (setsid ./${G_SUPERVISE_NAME} >/dev/null 2>&1 &)
    ${SLEEP} 1
    check
    if [ $? -ne 0 ]; then
        echo "start fail.."
        pkill -9 -f ${G_SUPERVISE_NAME}
        ${SLEEP} 1
        return 1
    fi 

    ok "start"
    return 0
}

stop()
{
    signal
    check
    if [ $? -ne 0 ]; then
        ok "stop"
        return 0
    fi

    for i in 1 2 3 4 5; do
        signal
        ${SLEEP} 1
        check
        if [ $? -ne 0 ]; then
            ok "stop"
            return 0
        fi
    done
    die "stop"
}

restart()
{
    stop
    start
    return 0
}

shutdown()
{
    killall -9 ${G_SUPERVISE_NAME}
    killall -9 ${G_PROC_NAME}
    killall -9 ${G_II_NAME}
    killall -9 ${G_SI_NAME}
    ok "Shutdown"
    return 0;
}

status()
{
    check
    if [ $? -eq 0 ]; then
        echo 'Running'
        return 0
    else
        echo 'Not running'
        return 1
    fi
}

case "${1}" in
start)
    start
    ;;
stop)
    stop
    ;;
restart)
    restart
    ;;
shutdown)
    shutdown
    ;;
status)
    status
    ;;
*)
    help
    ;;
esac
