#!/usr/bin/env bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
#

# qpid.stop script
#
# The script can be used to stop instances of Qpid Broker-J instances with given PIDs or all running Qpid Brokers for current user
# if no PID is provided.
# The script issues KILL TERM for found or specified Qpid Broker-J instances and waits for their termination
# for up to MAX_WAIT_PERIOD seconds.

SLEEP_DELAY=1
SEARCH=${QPID_STOP_SEARCH:-PNAME=QPBRKR}
MAX_WAIT_PERIOD=${QPID_STOP_MAX_WAIT_PERIOD:-360}

shutdown_brokers()
{
    pids=( "$@" )
    if [[ ${#pids[@]} == 1 ]]; then
        echo "Found Qpid Broker-J process with PID: ${pids[@]}"
    else
        echo "Found Qpid Broker-J processes with PIDs: ${pids[@]}"
    fi

    declare -a monitored_pids=()
    for pid in "${pids[@]}"
    do
        echo "Shutting down Qpid Broker-J with PID '$pid'"
        if kill $pid 2>/dev/null; then
            monitored_pids+=($pid)
        else
            echo "Cannot shutdown Qpid Broker-J with the PID '$pid'"
        fi
    done

    echo "Waiting for up to $MAX_WAIT_PERIOD seconds for process(es) to shutdown..."
    end_time=$(($SECONDS+$MAX_WAIT_PERIOD))
    while [[ ${#monitored_pids[@]} -ne 0 && "${SECONDS}" -lt ${end_time} ]]
    do
        for i in "${!monitored_pids[@]}"
        do
           pid=${monitored_pids[i]}
           if ! kill -0 ${pid} 2>/dev/null
           then
              unset 'monitored_pids[i]'
           fi
        done

        if [[ ${#monitored_pids[@]} -eq 0 ]]
        then
           break
        else
           sleep "${SLEEP_DELAY}"
        fi
    done

    if [[ ${#monitored_pids[@]} -ne 0 ]]; then
        echo "Process(es) with PID(s) ${monitored_pids[@]} did not shutdown within ${MAX_WAIT_PERIOD} seconds. Killing processes."
        for pid in "${monitored_pids[@]}"
        do
            echo "Killing Qpid Broker-J with PID '$pid'"
            kill -9 ${pid} 2>/dev/null
        done
        exit 1
    else
        echo "Qpid Broker-J process(es) terminated successfully"
    fi
}

main()
{
    arg_length=$#
    if [[ $arg_length -eq 0 ]] ; then
        pids=($(pgrep -f -U "${USER}" -- "${SEARCH}"))

        if [[ ${#pids[@]} -eq 0 ]]; then
            echo "No Qpid Broker-J process found running"
        else
            shutdown_brokers "${pids[@]}"
        fi
    elif [[ $arg_length -eq 1 && "$1" == "-h" ]] ; then
        echo "$0: script tries to stop instances of Qpid Broker-J with given PIDs or all running Qpid Broker-J instances if no PID is provided."
        echo "usage: $0 [pid...]"
    else
        pids=( "$@" )
        declare -a broker_pids=()
        for pid in "${pids[@]}"
        do
            ps -f -p $pid | grep -- "${SEARCH}" | grep -v grep >/dev/null
            if [[ $? -eq 0 ]]; then
                broker_pids+=($pid)
            else
                echo "Qpid Broker-J with the PID '$1' is not found"
            fi
        done

        if [[ ${#broker_pids[@]} != 0 ]]; then
            shutdown_brokers "${broker_pids[@]}"
        fi
    fi
}

main "$@"
