#!/bin/bash
#
# Copyright (c) Members of the EGEE Collaboration. 2006-2010.
# See http://www.eu-egee.org/partners/ for details on the copyright holders.
#
# 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.
#
# Startup script for PEP daemon server
#
# chkconfig: 345 97 97
#
# description: PEPd Server starting script
#
### BEGIN INIT INFO
# Provides:          argus-pepd
# Required-Start:    $network $remote_fs 
# Required-Stop:     $network $remote_fs 
# Default-Start:     3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start pep-daemon at boot time
# Description:       Provides the PEP-server function of the Argus-service
### END INIT INFO
#
# Author(s): Valery Tschopp <argus-support@cern.ch>
#            Joel Casutt <argus-support@cern.ch>
#
# Version: V2.2
# Date: 28/09/2012
###############################################################################
# set -x

# PEP server control script and name of the script
PEPDCTL="/usr/sbin/pepdctl"
NAME="argus-pepd"

if [ `id -u` -ne 0 ]; then
    echo "You need root privileges to run this script"
    exit 1
fi 

# Source functions Library
if [ -r "/lib/lsb/init-functions" ]; then
    source /lib/lsb/init-functions
else
    echo "/lib/lsb/init-functions must be present to run this script"
    exit 1
fi

PEPD_PROG="$NAME"
SHUTDOWN_WAIT=60
KILL_WAIT=15
HAS_LOCK=0
PEPD_LOCK=
PEPD_PID=${PEPD_PID:-"/var/run/$NAME.pid"}

# See if there is an appropriate location for the lock-file, if not, do not use a lock-file
if [ -d "/var/lock/subsys" ]; then
    PEPD_LOCK="/var/lock/subsys/$NAME"
    HAS_LOCK=1
elif [ -d "/var/lock" ]; then
    PEPD_LOCK="/var/lock/$NAME"
    HAS_LOCK=1
fi

# source optional system configuration
# from /etc/sysconfig dir on SL5/SL6
if [ -r "/etc/sysconfig/$NAME" ]; then
    # Auto-export variables to subsequent scripts
    set -a
    source "/etc/sysconfig/$NAME"
# from /etc/default dir on Debian6
elif [ -r "/etc/default/$NAME" ]; then
    # Auto-export variables to subsequent scripts
    set -a
    source "/etc/default/$NAME"
fi

# Function to start the PEPD daemon
function start() {
    echo -n "Starting $PEPD_PROG... "
    # get the current state of the program, this also creates appropriate pid and lock files
    # if the program is running but the files are missing.
    _current_state
    state=$?
    
    if [ $state -eq 0 ] || [ $state -eq 2 ] || [ $state -eq 3 ] || [ $state -eq 4 ]; then
        log_success_msg "process already running"
        return 0
    elif [ $state -eq 5 ]; then
        $PEPDCTL start
        if [ $HAS_LOCK -eq 1 ]; then
            touch $PEPD_LOCK
        fi
        # test if the start command has worked
        _current_state
        new_state=$?
        if [ $new_state -eq 0 ]; then
            log_success_msg
        elif [ $new_state -eq 2 ] || [ $new_state -eq 3 ] || [ $new_state -eq 4 ]; then
            log_warning_msg "process started but no PID and/or LOCK file created"
        else
            log_failure_msg
        fi
    else
        log_failure_msg
    fi
}

# Function to stop the PEPD
function stop() {
    echo -n "Stopping $PEPD_PROG... "
    _current_state
    state=$?
    
    if [ $state -eq 5 ]; then
        log_success_msg "no process found, nothing to do"
        return 0
    else
        count=0
        killed=false
        MAX_WAIT=$[$KILL_WAIT+$SHUTDOWN_WAIT]
        $PEPDCTL stop > /dev/null 2>&1
        read kpid < $PEPD_PID
        until [ $(ps --pid $kpid | grep -c $kpid) -eq 0 ]; do
            sleep 1
            let count=${count}+1
            if [ $count -ge $SHUTDOWN_WAIT ] && ! $killed; then
                echo -n "waited ${SHUTDOWN_WAIT} s, force kill"
                kill -9 $kpid
                killed=true
            fi
            if [ $count -ge $MAX_WAIT ]; then
                log_failure_msg
            fi
        done
        _current_state
        log_success_msg
    fi
}

# Function to read the status of the PEPD
function status() {
    _current_state
    state=$?
    if [ $state -eq 5 ]; then
        echo "$PEPD_PROG is not running..."
        return $state
    else
        echo "$PEPD_PROG is running..."
    fi
}

# Function to read the info of the PEPD
function info() {
    _current_state
    state=$?
    if [ $state -eq 5 ]; then
        echo "$PEPD_PROG is not running..."
        return $state
    else
        $PEPDCTL status
    fi
}

# Function to clear the cache of the PEPD
function clearcache() {
    _current_state
    state=$?
    if [ $state -eq 5 ]; then
        echo "$PEPD_PROG is not running..."
        return $state
    else
        $PEPDCTL clearResponseCache
    fi
}

# Function to read the version of the PEPD
function version() {
     _current_state
    $PEPDCTL version
}

# tests if the current process exists and if it has an associated pid and lock file. Return codes are as followed:
# 0 = process is running correctly (and has both, a pid and a lock file)
# 1 = the function exited unexpected (fatal error)
# 2 = process is running and has a lock file, but no pid file, The pid-file is created
# 3 = process is running and has a pid file, but no lock file. The lock-file is created
# 4 = process is running and has no pid and no lock file. Both files are created
# 5 = process is not running. Possible stale files are removed
function _current_state() {
    local pid=`pgrep -f org.glite.authz.pep.server.PEPDaemon`
    
    if [ -z $pid ]; then
        rm -f $PEPD_PID
        if [ $HAS_LOCK -eq 1 ]; then
            rm -f $PEPD_LOCK
        fi
        return 5
    fi
    if [ $HAS_LOCK -eq 1 ]; then
        if [ -f "$PEPD_LOCK" -a ! -f "$PEPD_PID" ]; then
            touch $PEPD_PID 2>&1
            echo $pid > $PEPD_PID
            return 2
        elif [ -f "$PEPD_PID" -a ! -f "$PEPD_LOCK" ]; then
            touch $PEPD_LOCK
            return 3
        elif [ -f "$PEPD_PID" -a -f "$PEPD_LOCK" ]; then
            return 0
        else
            touch $PEPD_PID 2>&1
            echo $pid > $PEPD_PID
            touch $PEPD_LOCK
            return 4
        fi
    else
        if [! -f "$PEPD_PID" ]; then
            touch $PEPD_PID 2>&1
            echo $pid > $PEPD_PID
            return 2
        else
            return 0
        fi
    fi  
}


case "$1" in
    start)
        start
        ;; 
    stop)
        stop
        ;;
    restart|force-reload)
        stop
        start
        ;;
    status)
        status
        ;;
    info)
        info
        ;;
    version)
        version
        ;;
     clearcache)
        clearcache
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|status|info|version|clearcache}"
        exit 1
        ;;
esac

exit $?
