#!/bin/bash
set -u

#==============================================================================
# Battle School SDP Push

#==============================================================================
# Declarations and Environment

# Version ID Block. Relies on +k filetype modifier.
#------------------------------------------------------------------------------
# shellcheck disable=SC2016
declare VersionID='$Id: //p4-sdp/dev_c2s/tools/bp.sh#2 $ $Change: 31472 $'
declare VersionStream=${VersionID#*//}; VersionStream=${VersionStream#*/}; VersionStream=${VersionStream%%/*};
declare VersionCL=${VersionID##*: }; VersionCL=${VersionCL%% *}
declare Version=${VersionStream}.${VersionCL}
[[ "$VersionStream" == r* ]] || Version="${Version^^}"

declare ThisScript=${0##*/}
declare -i ShowProgress=1
declare -i UpdateCount=0
declare -i ServerCount=0
declare -i ErrorCount=0
declare -i Debug=${DEBUG:-0}
declare RunHost=bos-helix-01
declare ThisHost=${HOSTNAME%%.*}
declare Timeout=7s
declare RsyncCmd=
declare RsyncLog=

#==============================================================================
# Local Functions.
function msg () { echo -e "$*"; }
function msgn () { echo -e -n "$*"; }
function dbg () { [[ "$Debug" -eq 0 ]] || msg "DEBUG: $*"; }
function errmsg () { msg "\\nError: ${1:-Unknown Erorr}\\n"; ErrorCount+=1; }
function bail () { errmsg "${1:-Unknown Erorr}"; exit "$ErrorCount"; }
function usage() {
   local style="${1:--h}"
   local usageError="${2:-}"

   msg "Usage for $ThisScript version $Version:

$ThisScript [-d]

or for help info:

$ThisScript [-h|-man]"

if [[ "$style" == -man ]]; then
   msg "
DESCRIPTION:
	This is the Battle School Push script.

	It is used in when a Battle School Lab Environment is used with
	an in situ workspace for SDP development.

	It pushes files from where they are versioned on the bos-helix-01
	machine to the rest of the servers in the Battle School topology,
	to keep the script versions sync for development and test work.
	This script can only be run from the bos-helix-01 machine.

	It uses rsync commands to do the push. The rsync commands are
	operated with a timeout and are considered to have failed if
	there is an unexpected delay.

EXAMPLES:
	EXAMPLE 1: Typical usage with no arguments:

	bp.sh

	EXAMPLE 2: Debug Mode:

	bp.sh -d
"
fi


   exit 2
}

#==============================================================================
# Command Line Processing

declare -i shiftArgs=0

set +u
while [[ $# -gt 0 ]]; do
   case $1 in
      (-h) usage -h;;
      (-man) usage -man;;
      (-d) Debug=1;;
      (-*) usage -h "Unknown option/flag ($1).";;
      (*) usage -h "Unknown parameter ($1).";;
   esac

   # Shift (modify $#) the appropriate number of times.
   shift; while [[ $shiftArgs -gt 0 ]]; do
      [[ $# -eq 0 ]] && usage -h "Incorrect number of arguments."
      shiftArgs=$shiftArgs-1
      shift
   done
done
set -u

[[ "$ThisHost" == "$RunHost" ]] ||\
   bail "Run from $RunHost, not $ThisHost."

msgn "Updating SDP files in Battle School Lab."
[[ "$ShowProgress" -eq 1 ]] && msgn "..."

RsyncLog=$(mktemp)

for h in helix-0{2..5}; do
   for d in /p4/sdp /p4/common; do
      UpdateCount+=1
      RsyncCmd="rsync -a $d/ $h:$d"
      dbg "Running: timeout $Timeout $RsyncCmd"
      if eval timeout $Timeout "$RsyncCmd" > "$RsyncLog" 2>&1; then
         dbg "Output:\\n$(cat "$RsyncLog")"
         [[ "$ShowProgress" -eq 1 ]] && msgn "."
      else
         errmsg "Error running [$RsyncCmd].  Output:\\n$(cat "$RsyncLog")"
         [[ "$ShowProgress" -eq 1 ]] && msgn "X"
      fi
   done

   RsyncCmd="rsync /p4/sdp/Version $h:/p4/sdp/Version"
   dbg "Running: $RsyncCmd"
   if eval "$RsyncCmd" > "$RsyncLog" 2>&1; then
      dbg "Output:\\n$(cat "$RsyncLog")"
      [[ "$ShowProgress" -eq 1 ]] && msgn "."
   else
      errmsg "Error running [$RsyncCmd].  Output:\\n$(cat "$RsyncLog")"
      [[ "$ShowProgress" -eq 1 ]] && msgn "X"
   fi
   UpdateCount+=1
   ServerCount+=1
done

rm -f "$RsyncLog"

if [[ "$ErrorCount" -eq 0 ]]; then
   msg "\\nOK: Pushed $UpdateCount updates to $ServerCount servers."
else
   msg "\\nSee above; $ErrorCount errors were encountered doing $UpdateCount updates to $ServerCount servers."
fi

exit "$ErrorCount"
