#!/bin/bash

# Part of the cosima cluster
# Update MEGAlib on the remote machines

# Return:
# Positive: number of available simulation slots


commandhelp() {
  echo ""
  echo "dmegalib-updatemegalib - update MEGAlib on the remote machines";
  echo "Copyright by Andreas Zoglauer"
  echo ""
  echo "Usage: dmegalib-updatemegalib [options]";
  echo ""
  echo "Options:"
  echo "  --branch=name             : Use the given MEGAlib git branch (default it master)"
  echo "  --machine=user@host:port  : Only update this machine, if not given use the ones in .dmegalib.cfg"
  echo "  --help                    : Show this help"
  echo ""
  echo "This script will: "
  echo " (1) install or update MEGAlib in ~/Science/Software" 
  echo " (2) create a .bash.local file which will be read everytime you start a remote run"
  echo "";
  echo "Example: "
  echo "  dmegalib-updatemegalib";
  echo "";
}


# Store command line as array
CMD=( "$@" )
SINGLEMACHINE=""
BRANCH="master"

# Check for help
for C in "${CMD[@]}"; do
  if [[ ${C} == *-m*=* ]]; then
    SINGLEMACHINE=`echo ${C} | awk -F"=" '{ print $2 }'` 
  elif [[ ${C} == *-b*=* ]]; then
    BRANCH=`echo ${C} | awk -F"=" '{ print $2 }'` 
  elif [[ ${C} == *-h* ]]; then
    echo ""
    commandhelp
    exit 0
  fi
done

# Default options:
CFG=~/.dcosima.cfg
if [ ! -f ${CFG} ]; then
  echo "ERROR: No dmegalib configuration file present. Please run dmegalib-setup first."
  exit 1
fi

MEGALIBPATH="~/Science/Software" # Attention hard coded else where!

# Read configuration file and extract machines
if [ "${SINGLEMACHINE}" == "" ]; then
  MACHINES=( `cat ${CFG} | grep "^machine" | gawk '{ print $2 }'` )
else 
  MACHINES=( "${SINGLEMACHINE}" )
fi
REMOTEUSER=( )
REMOTEHOST=( )
REMOTEPORT=( )
REMOTENAME=( )

echo " "
echo "Remote machines setup:"
for (( m=0; m<=$(( ${#MACHINES[*]} -1 )); m++ )); do

  REMOTEUSER[$m]=`echo "${MACHINES[$m]}" | awk -F"@" '{ print $1 }'` 
  REMOTEHOST[$m]=`echo "${MACHINES[$m]}" | awk -F"@" '{ print $2 }'  | awk -F":" '{ print $1 }'` 
  REMOTEPORT[$m]=`echo "${MACHINES[$m]}" | awk -F":" '{ print $2 }'`
 
  # Do a quick test if the machine is available:
  REMOTENAME[$m]=`ssh -i ${HOME}/.ssh/dmegalib_rsa -q -o ConnectTimeout=5 -p ${REMOTEPORT[$m]} ${REMOTEUSER[$m]}@${REMOTEHOST[$m]} "hostname"`
  if [ "$?" != "0" ]; then
    echo " * Machine ${REMOTEHOST[$m]}, port ${REMOTEPORT[$m]}, user ${REMOTEUSER}: NOT ACCESSIBLE"
    MACHINES[$m]=""
    continue
  fi  

  echo " * Machine ${REMOTENAME[$m]} (user: ${REMOTEUSER[$m]}, address: ${REMOTEHOST[$m]}, port: ${REMOTEPORT[$m]}): FOUND"

done


# Create a temporary script which we will execute later
SCRIPT=$(mktemp /tmp/dmegalib-meglibupdate-script.XXXXXXXXXX)
cat <<EOT >> ${SCRIPT}
#/bin/bash

# For testing
#uname -a
#sleep 10
#echo "DMEGALIBERROR 1"
#exit 1

# Check if the MEGAlib path exits, if not create it
if [[ ! -d ${MEGALIBPATH} ]]; then 
  mkdir -p ${MEGALIBPATH}; 
  if [ "\$?" != "0" ]; then
    echo "DMEGALIBERROR 1"
    exit 1
  fi
fi

# If the MEGAlib dir exists and has a git repository, stash any changes 
if [[ -d ${MEGALIBPATH}/MEGAlib ]]; then
  cd ${MEGALIBPATH}/MEGAlib;
  if [[ -d .git ]]; then
    git stash save
    if [ "\$?" != "0" ]; then
      echo "DMEGALIBERROR 2"
      exit 2
    fi
  fi
fi

# Download setup script
cd ${MEGALIBPATH}; 
curl -O https://raw.githubusercontent.com/zoglauer/megalib/${BRANCH}/setup.sh
if [ "\$?" != "0" ]; then
  echo "DMEGALIBERROR 3"
  exit 3
fi

# Execute setup script
bash setup.sh --rel=dev --deb=off --opt=hard --patch=on --cleanup=on --branch=${BRANCH}
if [ "\$?" != "0" ]; then
  echo "DMEGALIBERROR 4"
  exit 4
fi

# Setup environment
SOURCE="test -e ~/Science/Software/MEGAlib/bin/source-megalib.sh && . ~/Science/Software/MEGAlib/bin/source-megalib.sh"; 
HASIT=""; 
if [[ -f ~/.bash_local ]]; then 
  HASIT=\$(grep "\${SOURCE}" ~/.bash_local); 
fi; 
if [ "\${HASIT}" == "" ]; then 
  echo \${SOURCE} >> ~/.bash_local; 
fi
SOURCE="umask 007"; 
HASIT=""; 
if [[ -f ~/.bash_local ]]; then 
  HASIT=\$(grep "\${SOURCE}" ~/.bash_local); 
fi; 
if [ "\${HASIT}" == "" ]; then 
  echo \${SOURCE} >> ~/.bash_local; 
fi

source ~/Science/Software/MEGAlib/bin/source-megalib.sh
if [ "\$?" != "0" ]; then
  echo "DMEGALIBERROR 5"
  exit 5
fi

# Run a quick test simulation
m
rm -rf RunTestHeaven.*.sim
rm -rf RunTestSky.*.sim
cosima
if [ "\$?" != "0" ]; then
  echo "DMEGALIBERROR 6"
  exit 6
fi
if [[ ! -f RunTestHeaven.inc1.id1.sim ]] || [[ ! -f RunTestSky.inc1.id1.sim ]]; then 
  echo "DMEGALIBERROR 6"
  exit 6
fi
rm -rf RunTestHeaven.*.sim
rm -rf RunTestSky.*.sim

exit 0

EOT

echo " "
echo "Kicking off update on "
 
# Create the install paths on all machines
for (( m=0; m<=$(( ${#MACHINES[*]} -1 )); m++ )); do

  if [ "${MACHINES[$m]}" == "" ]; then
    continue;
  fi

  echo " * ${REMOTENAME[$m]} - ${REMOTEUSER[$m]}@${REMOTEHOST[$m]}:${REMOTEPORT[$m]}"
  ssh -i ${HOME}/.ssh/dmegalib_rsa -p ${REMOTEPORT[$m]} ${REMOTEUSER[$m]}@${REMOTEHOST[$m]} "bash -s" -- < ${SCRIPT} > /tmp/dmegalib-${REMOTENAME[$m]}.log 2>&1 &
  sleep 5 # Sleep a bit in case the machines share storage
  
done

echo " "
echo "Waiting for all remote processes to finish..."
wait

rm -r ${SCRIPT}

echo " "
echo "Installation status: "

# Create a failed list
for (( m=0; m<=$(( ${#MACHINES[*]} -1 )); m++ )); do

  if [ "${MACHINES[$m]}" == "" ]; then
    echo " * ${REMOTEUSER[$m]}@${REMOTEHOST[$m]}:${REMOTEPORT[$m]} - ERROR: Unable to log in"
    continue;
  fi
  
  if grep -q "DMEGALIBERROR 1" "/tmp/dmegalib-${REMOTENAME[$m]}.log"; then
    echo " * ${REMOTENAME[$m]} - ERROR: Unable to create MEGAlib path. See \"/tmp/dmegalib-${REMOTENAME[$m]}.log\" for more details."
    continue;
  fi
  if grep -q "DMEGALIBERROR 2" "/tmp/dmegalib-${REMOTENAME[$m]}.log"; then
    echo " * ${REMOTENAME[$m]} - ERROR: Unable to stash the old MEGAlib version. See \"/tmp/dmegalib-${REMOTENAME[$m]}.log\" for more details."
    continue;
  fi
  if grep -q "DMEGALIBERROR 3" "/tmp/dmegalib-${REMOTENAME[$m]}.log"; then
    echo " * ${REMOTENAME[$m]} - ERROR: Unable to download the setup script. See \"/tmp/dmegalib-${REMOTENAME[$m]}.log\" for more details."
    continue;
  fi
  if grep -q "DMEGALIBERROR 4" "/tmp/dmegalib-${REMOTENAME[$m]}.log"; then
    echo " * ${REMOTENAME[$m]} - ERROR: An error occurred while running the setup script. See \"/tmp/dmegalib-${REMOTENAME[$m]}.log\" for more details."
    continue;
  fi
  if grep -q "DMEGALIBERROR 5" "/tmp/dmegalib-${REMOTENAME[$m]}.log"; then
    echo " * ${REMOTENAME[$m]}: Unable to source the MEGAlib script. See \"/tmp/dmegalib-${REMOTENAME[$m]}.log\" for more details."
    continue;
  fi
  if grep -q "DMEGALIBERROR 6" "/tmp/dmegalib-${REMOTENAME[$m]}.log"; then
    echo " * ${REMOTENAME[$m]}: Unable to run test simulation. See \"/tmp/dmegalib-${REMOTENAME[$m]}.log\" for more details."
    continue;
  fi
  
  # Only keep the ones with error messages
  rm -rf /tmp/dmegalib-${REMOTENAME[$m]}.log
  
  echo " * ${REMOTENAME[$m]} - SUCCESS"
  
done

echo " "

dmegalib-checkmegalib

exit 0
