#!/usr/bin/bash

command="$0 $*"
params="$(getopt -o s:r:t:R: -l state:,any,timeout:,retry: --name "$(basename -- "$0")" -- "$@")"

function usage ()
{
    cat <<EOF
Usage:
        $0 -s <STATE> [-s <STATE>] [OPTION...] <MACHINE> [<MACHINE>] .. [<MACHINE>]

Sets the state for the local machine.  Used for simple multi-host testing.

Help Options:
 -h, --help     Show help options

Application Options:
 -s, --state=STATE      Blocks on the current state
 -t, --testorder=ORDER  override the task/test order
     --any		If any machine matches exit
     --timeout=TIMEOUT	Set a timeout
     --retry=TIME       Time to pause between retries
EOF

    exit 1
}

eval set -- "$params"
unset params

basename=$(basename -- $0)
if [ "$basename" = "rhts-sync-block" -o \
     "$basename" = "rhts_sync_block" -o \
     "$basename" = "rstrnt-sync-block" ]; then
    XTRA="${TASKORDER}"
fi

rsync=$(which rstrnt-sync)
if [ -z "$rsync" ]; then
    echo "rstrnt-sync binary missing! - $0 won't work!"
    exit 1
fi

any=0
states=""
pause=60
while true
do
    case $1 in
        -s|--state)
            shift
            states="$states ${XTRA}_$1"
            shift
            ;;
        --any)
            shift
            any=1
            ;;
        --timeout)
            shift
            timeout=$(date +%s --date "+$1 seconds")
            shift
            ;;
        --retry)
            shift
            pause=$1
            shift
            ;;
        -t|--testorder)
            shift
            shift
            ;;
        --)
            shift
            break
            ;;
        *)
            usage
            ;;
    esac
done

if [ -z "$*" ]; then
    usage
fi

echo "$command -- Blocking state(s) = $states"

while true
do
    fail=0
    for machine in $@; do
        for state in $states; do
            output=$(rstrnt-sync block ${state} ${machine} 10 2>&1)
            rc=$?
            if [ $rc -eq 0 ]; then
                if [ $any -eq 1 ]; then
                    break 3
                fi
                break
            fi
        done
        if [ $rc -ne 0 ]; then
            fail=1
            if [ -n "$timeout" ]; then
                time=$(date +%s)
                if [ "$timeout" -le "$time" ]; then
                    echo "$0: timeout $timeout exceeded"
                    break 2
                fi
            fi
            # If we get any error besides the timeout we sleep for a minute
            if [ $rc -ne 37 ]; then
                if [ -z "$output" ]; then
                    echo "Failed rstrnt-sync block ${state} ${machine} result: $rc"
                else
                    echo $output
                fi
                sleep $pause
            fi
        fi
    done
    if [ $fail -eq 0 ]; then
        break
    fi
    echo "Retrying rstrnt-sync-block for state ${state}"
done
exit $rc
