#!/bin/bash

##
# Copyright 2015 Telefonica Investigacion 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"   && 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/osm-ro.service ]] && [[ -z $option_screen_name ]] && running=y #&& service osm-ro 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/osm-ro.service ]] && [[ -z $option_screen_name ]] && service osm-ro $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




