#!/bin/sh
### BEGIN INIT INFO
# Provides:          angie
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Angie web server
### END INIT INFO

DAEMON=/usr/sbin/angie
CONF=/etc/angie/angie.conf
PIDFILE=/run/angie.pid
LOCKFILE=/run/angie.init.lock

NAME=angie
DESC="Angie - high performance web server"

CHECK_PAUSE=${CHECK_PAUSE:-1}
CHECK_TRIES=${CHECK_TRIES:-30}
STABILITY_WAIT=${STABILITY_WAIT:-5}


. /lib/lsb/init-functions

test -x "$DAEMON" || exit 0

exec 9>"$LOCKFILE" || exit 1
flock -n 9 || {
    echo "Another init action is running" >&2
    exit 1
}

do_configtest() {
    log_daemon_msg "Checking config"
    "$DAEMON" -t -c "$CONF"
    RETVAL=$?
    log_end_msg "$RETVAL"
    return $RETVAL
}

is_real_angie() {
    PID=$(cat "$PIDFILE" 2>/dev/null) || return 1
    ps -p "$PID" -o comm= 2>/dev/null | grep -q "^angie$"
}

is_running() {
    /sbin/start-stop-daemon --status \
        --pidfile "$PIDFILE" >/dev/null 2>&1 \
        && is_real_angie
}

wait_for_pid() {
    i=0
    while [ "$i" -lt 10 ]; do
        [ -f "$PIDFILE" ] && return 0
        sleep 1
        i=$((i+1))
    done
    return 1
}

fail_fast_check() {
    sleep 1
    is_running
}

start() {
    log_daemon_msg "Starting $DESC"

    if is_running; then
        log_progress_msg "already running"
        log_end_msg 0
        return 0
    fi

    do_configtest || return 1

    start-stop-daemon \
        --start \
        --quiet \
        --pidfile "$PIDFILE" \
        --exec "$DAEMON" \
        -- -c "$CONF"

    if ! wait_for_pid || ! fail_fast_check; then
        echo "Daemon failed right after start!" >&2
        log_end_msg 1
        RETVAL=1
        return 1
    fi

    RETVAL=$?
    log_end_msg "$RETVAL"
}

stop() {
    log_daemon_msg "Stopping $DESC"

    start-stop-daemon \
        --stop \
        --quiet \
        --pidfile "$PIDFILE" \
        --exec "$DAEMON" \
        --retry=QUIT/30/TERM/10/KILL/5 \
        --oknodo

    RETVAL=$?
    log_end_msg "$RETVAL"
}

reload() {

    do_configtest || return 1

    if ! is_running; then
        echo "Not running — starting instead"
        start
        RETVAL=$?
        return $RETVAL
    fi

    log_daemon_msg "Reloading $DESC"

    start-stop-daemon \
        --stop \
        --signal HUP \
        --quiet \
        --pidfile "$PIDFILE" \
        --exec "$DAEMON"

    RETVAL=$?
    log_end_msg "$RETVAL"
}

restart() {
    log_daemon_msg "Restarting $DESC"

    do_configtest || return 1

    if ! is_running; then
        start
        return $?
    fi

    start-stop-daemon \
        --stop \
        --signal HUP \
        --quiet \
        --pidfile "$PIDFILE" \
        --exec "$DAEMON"

    RETVAL=$?
    log_end_msg "$RETVAL"
}

upgrade() {
    log_daemon_msg "Binary upgrade"

    do_configtest || {
        log_end_msg 1
        return 1
    }

    if ! is_running; then
        log_progress_msg "not running"
        log_end_msg 1
        RETVAL=1
        return 1
    fi

    OLDPIDFILE="${PIDFILE}.oldbin"

    kill -USR2 "$(cat "$PIDFILE")"

    i=0
    while [ "$i" -lt "$CHECK_TRIES" ]; do
        sleep "$CHECK_PAUSE"

        if [ -f "$OLDPIDFILE" ] && is_running; then

            NEWPID=$(cat "$PIDFILE")

            if kill -0 "$NEWPID" 2>/dev/null; then

                sleep "$STABILITY_WAIT"

                if ! kill -0 "$NEWPID" 2>/dev/null; then
                    echo "New master died — rollback!" >&2
                    kill -HUP "$(cat "$OLDPIDFILE")"
                    log_end_msg 1
                    RETVAL=1
                    return 1
                fi

                kill -QUIT "$(cat "$OLDPIDFILE")"
                log_end_msg 0
                return 0
            fi
        fi

        i=$((i+1))
    done

    echo "Upgrade failed!" >&2
    log_end_msg 1
    return 2
}

status() {
    status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME"
}

configtest() {
    do_configtest
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        restart
        ;;
    reload)
        reload
        ;;
    upgrade)
        upgrade
        ;;
    status)
        status
        ;;
    configtest)
        configtest
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|reload|upgrade|status|configtest}"
        exit 2
        ;;
esac

exit "$RETVAL"
