#!/bin/bash -e
source $OPENSHIFT_CARTRIDGE_SDK_BASH

# Set the sync source base dir
SYNC_BASE_DIR=$OPENSHIFT_PRIMARY_CARTRIDGE_DIR

# Check if we are syncing to a new gear
new_gear="false"
if [ -n "$1" ]; then
    new_gear="true"
fi

# Defines the default pre sync actions, taking into account
# the hot_deploy marker.
function set_default_pre_actions {
  OPENSHIFT_SYNC_GEARS_PRE=('gear stop')

  # Only respect hot deployment for initialized gears
  if [ "$new_gear" = "false" ]; then
    if hot_deploy_marker_is_present; then
      echo "Application will not be stopped during gear sync to to presence of hot_deploy marker"
      OPENSHIFT_SYNC_GEARS_PRE=()
    fi
  fi
}

# Defines the default post sync actions, taking into account
# the hot_deploy marker.
function set_default_post_actions {
    remote_deploy_cmd="gear remotedeploy"

    if [ "$new_gear" = "true" ]; then
      remote_deploy_cmd="${remote_deploy_cmd} --init"
    else
      # Only respect hot deployment for initialized gears
      if hot_deploy_marker_is_present; then
        remote_deploy_cmd="${remote_deploy_cmd} --hot-deploy"
      fi
    fi

    OPENSHIFT_SYNC_GEARS_POST=("${remote_deploy_cmd}")
}

# Defaults for sync-gears.  Override these in .env from the configure script
[ -z "$OPENSHIFT_SYNC_GEARS_DIRS" ] && OPENSHIFT_SYNC_GEARS_DIRS=( "../app-root/repo" "node_modules" "virtenv" "../.m2" ".openshift" "deployments" "perl5lib" "phplib" )
[ -z "$OPENSHIFT_SYNC_GEARS_PRE" ] && set_default_pre_actions
[ -z "$OPENSHIFT_SYNC_GEARS_POST" ] && set_default_post_actions
declare -ax OPENSHIFT_SYNC_GEARS_DIRS OPENSHIFT_SYNC_GEARS_PRE OPENSHIFT_SYNC_GEARS_POST


rsynccmd="rsync -v --delete-after -az"
if [ -f ${SYNC_BASE_DIR}/metadata/rsync.excludes ]; then
    rsynccmd="rsync --exclude-from=${SYNC_BASE_DIR}metadata/rsync.excludes --delete-after -az"
fi

export RSYNC_RSH="ssh"

# Fix to get name of haproxy cartridge from environment
HAPROXY_CONF_DIR=$OPENSHIFT_HAPROXY_DIR/conf
HAPROXY_GEAR_REGISTRY=$HAPROXY_CONF_DIR/gear-registry.db

# Manage sync tasks in parallel
if [ -n "$1" ]; then
   GEARSET[0]="$1"
else
   GEARSET=($(< "${HAPROXY_GEAR_REGISTRY}"))
fi
STDOUTS=()   # Set of outputs
EXITCODES=() # Set of exit codes

for zinfo in "${GEARSET[@]}"
do
  zarr=(${zinfo//;/ })
  gear=${zarr[0]}
  arr=(${gear//:/ })
  sshcmd="ssh ${arr[0]}"
  echo "SSH_CMD: ${sshcmd}"
  #output=$(mktemp "${SYNC_BASE_DIR}/tmp/sync_gears.output.XXXXXXXXXXXXXXXX")
  output=$(mktemp "/tmp/sync_gears.output.XXXXXXXXXXXXXXXX")
  STDOUTS+=("$output")
  #exitcode=$(mktemp "${SYNC_BASE_DIR}/tmp/sync_gears.exit.XXXXXXXXXXXXXXXX")
  exitcode=$(mktemp "/tmp/sync_gears.exit.XXXXXXXXXXXXXXXX")
  EXITCODES+=("$exitcode")
  (
    (
      set -x -e
      echo "Syncing to gear: $gear @ " $(date)

      # Prepare remote gear for new content
      for rpccall in "${OPENSHIFT_SYNC_GEARS_PRE[@]}"
      do
        $sshcmd "$rpccall"
      done

      # Push content to remote gear
      for subd in "${OPENSHIFT_SYNC_GEARS_DIRS[@]}"
      do
        if [ -d "${SYNC_BASE_DIR}/${subd}" ]
        then
          $rsynccmd "${SYNC_BASE_DIR}/${subd}/" "${gear}/${subd}/"
        fi
      done

      # Post-sync calls & start
      for rpccall in "${OPENSHIFT_SYNC_GEARS_POST[@]}"
      do
        $sshcmd "$rpccall"
      done

    )
    echo $? > "$exitcode"
  ) >"$output" 2>&1 &
done
wait

# Serialize outputs and exit codes for easier debugging
exc=0
slen=${#STDOUTS[@]}
for (( i=0; i<${slen}; i++ ))
do
  cat "${STDOUTS[$i]}"
  pexc=$(cat "${EXITCODES[$i]}")
  echo "Exit code: $pexc"
  if [ "$pexc" != "0" ]; then
    exc=128   # TODO: instead? exc=$(($exc | $pexc))
  fi
  rm -f "${STDOUTS[$i]}" "${EXITCODES[$i]}"
done

exit $exc
