#!/bin/sh
#
#  Wait for dCache to have certain cells present.  The function will time-out if
#  dCache takes too long to respond that all requested cells have started.
#


[ -f /etc/default/dcache ] && . /etc/default/dcache       
[ -f /etc/dcache.env ] && . /etc/dcache.env               

if [ -z "$DCACHE_HOME" ]; then                            
DCACHE_HOME="/usr/share/dcache"                         
fi                                                        
if [ ! -d "$DCACHE_HOME" ]; then                          
echo "$DCACHE_HOME is not a directory"                  
exit 2                                                  
fi                                                        

DCACHE_CLASSPATH=${DCACHE_HOME}/classes/*                 
DCACHE_DEFAULTS=${DCACHE_HOME}/defaults                   
DCACHE_CACHED_CONFIG=/var/lib/dcache/config/cache         
. ${DCACHE_HOME}/lib/loadConfig.sh                        
if [ "$(id -u)" -eq 0                                       -a -f /lib/systemd/system-generators/dcache-generator  -a "$(basename $0)" != "dcache-generator"              -a -f /bin/systemctl ]; then                         
for unit in /run/systemd/generator/dcache@*.service; do 
if [ "$DCACHE_CACHED_CONFIG" -nt "$unit" ]; then      
systemctl daemon-reload                             
break                                               
fi                                                    
done                                                    
fi

set -e

# Default polling frequency, in seconds.
poll=$(getProperty wait-for-cells.poll)

# Our return code; default is 0 (=> OK)
rc=0

xslt_dir=$(getProperty dcache.paths.xslt)
host=$(getProperty wait-for-cells.http.host)
port=$(getProperty wait-for-cells.http.port)

usage()
{
    echo "Usage:"
    echo "   `basename $0` [-p <poll freq>] [-d | --dots] [-l | --list-missing]"
    echo "                     [-H <host>] [-P <port>] <timeout> <cell> [<cell> ...]"
    echo
    echo "Checks every <poll freq> seconds (${poll}s by default) whether the listed cells are up."
    echo "Obtains dCache current status by querying the web interface.  By default, this is"
    echo "assumed to be running on the local machine, but the location may be configured in"
    echo "dcache.conf; the local may also be set explicitly using the -H and -P options."
    echo
    echo "All <cell>s are specified as <cell-name>@<domain-name> or <well-known-cell-name>"
    echo
    echo "If -d is specified then a dot is printed each time the info service is queried without"
    echo "finding all cells.  If -l is specified then the list of missing cells is listed if the"
    echo "timeout is reached without all cells being found."
    echo
    echo "Returns:"
    echo "    0 if all cells are up,"
    echo "    1 if at least one cell was not after waiting for <timeout> seconds,"
    echo "    5 if parameters to this script are wrong."
}

while [ $# -gt 1 ]; do
    case $1 in
	-p)
	    shift
	    poll=$1
	    shift
	    ;;

        -P)
	    shift
	    port=$1
	    shift
	    ;;

        -h | --help)
	    usage
	    exit 5
	    ;;

	-d | --dots)
	    dots=1
	    shift
	    ;;

	-l | --list-missing)
	    list_missing=1
	    shift
	    ;;

	-H)
	    shift
	    host=$1
	    shift
	    ;;

	-*)
	    echo "Unknown option $1"
	    echo
	    usage
	    exit 5
	    ;;

	*)
	    # Assume the remaining arguments are the required args.
	    break;
	    ;;
    esac
done

if [ $# -lt 2 ]
then
    usage
    exit 5
fi

timeout=$1
shift

cells="$@"

if [ "$timeout" -lt $poll ]; then
  echo Timeout $timeout is less that minimum $poll
  exit 5
fi

#
#  See which cells are currently missing
#
list_missing_cells()
{
    xsltproc --stringparam cells "$cells" $xslt_dir/wait-for-cells.xsl "http://$host:$port/info/domains" 2>/dev/null || echo "Missing: $cells"
}

#
#  Loop, waiting for either timeout or cells to come up.
#
timeout=$(date -d "$timeout seconds" +%s)

while :; do
  now=$(date +%s)

  if [ $now -gt $timeout ]; then
      # One or more cells were not up by timeout, exit with rc=1
      rc=1
      break
  fi

  list_missing_cells | grep "Missing:" >/dev/null || break

  if [ "x$dots" = "x1" ]; then
      echo -n "."
      have_dots=1
  fi

  sleep $poll
done


#
# Tidy up and exit.
#

if [ "x$have_dots" = "x1" ]; then
    echo
fi

if [ $rc -ne 0 -a "$list_missing" = 1 ]; then
  list_missing_cells
fi

exit $rc
