#!/bin/bash

##
# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
# This file is part of openmano
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact with: nfvlabs@tid.es
##


#launch openmano inside a screen.
#or call service if it is installed on systemd


DIRNAME=$(readlink -f ${BASH_SOURCE[0]})
DIRNAME=$(dirname $DIRNAME )
DIR_OM=$(dirname $DIRNAME )

function usage(){
    echo -e "Usage: $0 [openmano/mano] start|stop|restart|status"
    echo -e "  Launch|Removes|Restart|Getstatus openmano on a screen/service"
    echo -e "    -n --screen-name NAME : name of screen to launch openmano (default mano or service)"
    echo -e "    -h --help: shows this help"
    echo -e "    -- PARAMS use to separate PARAMS that will be send to the service. e.g. -pPORT -PADMINPORT --dbname=DDBB"
}


function kill_pid(){
    #send TERM signal and wait 5 seconds and send KILL signal ir still running
    #PARAMS: $1: PID of process to terminate
    kill $1 #send TERM signal
    WAIT=5
    while [ $WAIT -gt 0 ] && ps -o pid -U $USER -u $USER | grep -q $1
    do
        sleep 1
        WAIT=$((WAIT-1))
        [ $WAIT -eq 0 ] && echo -n "sending SIGKILL...  " &&  kill -9 $1  #kill when count reach 0
    done
    echo "done"
}

#process options
source ${DIRNAME}/get-options.sh "screen-name:n= help:h --" $* || exit 1

#help
[ -n "$option_help" ] && usage && exit 0


#obtain parameters
om_list=""
#om_action="start"  #uncoment to get a default action
action_list=""
om_params="$option__"

for param in $params
do
    [ "$param" == "start" -o "$param" == "stop"  -o "$param" == "restart" -o "$param" == "status" ] && om_action=$param  && continue
    [ "$param" == "openmano" -o "$param" == "mano" ]   && om_list="$om_list mano"             && continue
    #short options
    echo "invalid argument '$param'?  Type -h for help" >&2 && exit 1
done

[[ -n $option_screen_name ]] && option_screen_name=${option_screen_name#*.} #allow the format 'pid.name' and keep only name
#check action is provided
[ -z "$om_action" ] && usage >&2 && exit -1

#if no componenets supplied assume all
[ -z "$om_list" ] && om_list="mano"
 
function find_process_id(){ #PARAMS:  command screen-name
    for process_id in `ps -o pid,cmd -U $USER -u $USER | grep -v grep | grep "${1}" | awk '{print $1}'`
    do
        scname=$(ps wwep $process_id | grep -o 'STY=\S*')
        scname=${scname#STY=}
        [[ -n "$2" ]] && [[ "${scname#*.}" != "$2" ]] && continue
        echo -n "${process_id} "
    done
    echo
}

for om_component in $om_list
do
    screen_name="${om_component}"
    [[ -n "$option_screen_name" ]] && screen_name=$option_screen_name
    [ "${om_component}" == "mano" ] && om_cmd="./openmanod.py"   && om_name="openmano  " && om_dir=$(readlink -f ${DIR_OM})
    #obtain PID of program
    component_id=`find_process_id "${om_cmd}" $option_screen_name`
    processes=$(echo $component_id | wc -w)

    #status
    if [ "$om_action" == "status" ]
    then
        running=""
        for process_id in $component_id
        do
            scname=$(ps wwep $process_id | grep -o 'STY=\S*')
            scname=${scname#STY=}
            [[ -n "$option_screen_name" ]] && [[ "${scname#*.}" != "$option_screen_name" ]] && continue
            printf "%-15s" "pid: ${process_id},"
            [[ -n "$scname" ]] && printf "%-25s" "screen: ${scname},"
            echo cmd: $(ps -o cmd p $process_id | tail -n1 )
            running=y
        done
        #if installed as a service and it is not provided a screen name call service
        [[ -f /etc/systemd/system/openmano.service ]] && [[ -z $option_screen_name ]] && running=y #&& service openmano status
        if [ -z "$running" ]
        then
            echo -n "    $om_name not running" && [[ -n "$option_screen_name" ]] && echo " on screen '$option_screen_name'" || echo
        fi
    fi

    #if installed as a service and it is not provided a screen name call service
    [[ -f /etc/systemd/system/openmano.service ]] && [[ -z $option_screen_name ]] && service openmano $om_action && ( [[ $om_action == status ]] || sleep 5 ) && exit $?


    #stop
    if [ "$om_action" == "stop" -o "$om_action" == "restart" ]
    then
        #terminates program
        [ $processes -gt 1 ] && echo "$processes processes are running, specify with --screen-name" && continue
        [ $processes -eq 1 ] && echo -n "    stopping $om_name ... " && kill_pid $component_id
        component_id=""
        #terminates screen
        if screen -wipe | grep -q -e  "\.${screen_name}\b" 
        then
            screen -S $screen_name -p 0 -X stuff "exit\n" || echo
            sleep 1
        fi
    fi

    #start
    if [ "$om_action" == "start" -o "$om_action" == "restart" ]
    then
        #calculates log file name
        logfile=""
        mkdir -p $DIR_OM/logs && logfile=$DIR_OM/logs/open${screen_name}.log || echo "can not create logs directory  $DIR_OM/logs"
        #check already running
        [ -n "$component_id" ] && echo "    $om_name is already running. Skipping" && continue
        #create screen if not created
        echo -n "    starting $om_name ... "
        if ! screen -wipe | grep -q -e "\.${screen_name}\b"
        then
            pushd ${om_dir} > /dev/null
            screen -dmS ${screen_name}  bash
            sleep 1
            popd > /dev/null
        else
            echo -n " using existing screen '${screen_name}' ... "
            screen -S ${screen_name} -p 0 -X log off
            screen -S ${screen_name} -p 0 -X stuff "cd ${om_dir}\n"
            sleep 1
        fi
        #move old log file index one number up and log again in index 0
        if [[ -n $logfile ]]
        then
            for index in 8 7 6 5 4 3 2 1
            do
                [[ -f ${logfile}.${index} ]] && mv ${logfile}.${index} ${logfile}.$((index+1))
            done
            [[ -f ${logfile} ]] && mv ${logfile} ${logfile}.1
            screen -S ${screen_name} -p 0 -X logfile ${logfile}
            screen -S ${screen_name} -p 0 -X log on
        fi
        #launch command to screen
        screen -S ${screen_name} -p 0 -X stuff "${om_cmd}${om_params}\n"
        #check if is running
        [[ -n $logfile ]] && timeout=120 #2 minute
        [[ -z $logfile ]] && timeout=20
        while [[ $timeout -gt 0 ]]
        do
           #check if is running
           #echo timeout $timeout
           #if !  ps -f -U $USER -u $USER | grep -v grep | grep -q ${om_cmd}
           log_lines=0
           [[ -n $logfile ]] && log_lines=`head ${logfile} | wc -l`
           component_id=`find_process_id "${om_cmd}${om_params}" $screen_name`
           if [[ -z $component_id ]]
           then #process not started or finished
               [[ $log_lines -ge 2 ]] &&  echo -n "ERROR, it has exited." && break
               #started because writted serveral lines at log so report error
           fi
           [[ -n $logfile ]] && grep -q "open${om_component}d ready" ${logfile} && break
           sleep 1
           timeout=$((timeout -1))
        done
        if [[ -n $logfile ]] && [[ $timeout == 0 ]] 
        then 
           echo -n "timeout!"
        else
           echo -n "running on 'screen -x ${screen_name}'."
        fi
        [[ -n $logfile ]] && echo "  Logging at '${logfile}'" || echo
    fi
done




