#!/bin/bash

trap clean_up SIGHUP SIGINT SIGTERM SIGKILL

#function to help with the usage
function _print_syntax() {
  me=`basename "$0"`
  echo "Usage: $me [-d <dir> -l <dir> -w <num> -r <server>]"
  echo -e "\t-d <dir>\tDirectory of source code. If not provided /vagrant ist used"
  echo -e "\t-l <dir>\tDirectory where the logfiles should be put. If not set STDERR and STDOUT will be printed to console"
  echo -e "\t-w <num>\tNumber of workers that should be spawned. This can reduce the performance of the system!"
  echo -e "\t-r <server>\tRegister to this reposerver. Can be used multiple times."
}

#reset OPTIND
OPTIND=1

#preset GIT_HOME
GIT_HOME="/vagrant"

#preset WORKER_COUNT
WORKER_N=1

#preset reg_server
haverep=0
REP_SERVER_STRING="--reposerver http://localhost:5252"

#get options and check if there is a space in the dir arguments
while getopts "l:d:w:r:h?" opt; do
  case "$opt" in
  l)
    REDIR_LOG=$OPTARG
    if [[ "REDIR_LOG" =~ [[:space:]] ]]; then
      echo "Directory may not contain whitespaces"
      exit
    fi
    ;;
  d)
    GIT_HOME=$OPTARG
    if [[ "$GIT_HOME" =~ [[:space:]] ]]; then
      echo "Directory may not contain whitespaces"
      exit
    fi
    ;;
  w)
    WORKER_N=$OPTARG
    ;;
  r)
    rep_server+=("$OPTARG")
    haverep=1
    ;;
  h|\?)
    _print_syntax
    exit 0
    ;;
  esac
done

#REDIR_LOG points to the directory where the logfiles should be created. If the directory does not
#exist it will be created. APPEND_ARR[*] is filled with the output redirection for each service.
if [ -n "$REDIR_LOG" ]; then
  if [ ! -d "$REDIR_LOG" ]; then
    echo "$REDIR_LOG does not exist. Will try to create it"
    mkdir -p "$REDIR_LOG" || { echo "Failure in creating directory:"; print_error; exit; }
  fi
  APPEND_ARR[0]=">$REDIR_LOG/bs_srcserver.log 2>&1"
  APPEND_ARR[1]=">$REDIR_LOG/bs_repserver.log 2>&1"
  APPEND_ARR[2]=">$REDIR_LOG/bs_sched_i586.log 2>&1"
  APPEND_ARR[3]=">$REDIR_LOG/bs_sched_x86_64.log 2>&1"
  APPEND_ARR[4]=">$REDIR_LOG/bs_dispatch.log 2>&1"
  APPEND_ARR[5]=">$REDIR_LOG/bs_publish.log 2>&1"
  APPEND_ARR[6]=">$REDIR_LOG/bs_service.log 2>&1"
  w_count=1
  while [ $w_count -le $WORKER_N ]
  do 
    index=6+$w_count
    APPEND_ARR[$index]=">$REDIR_LOG/bs_worker_$w_count.log 2>&1"
    let w_count=$w_count+1
  done
fi

if [[ "$haverep" -eq "1" ]]; then
  REP_SERVER_STRING=""
  REP_PREFIX="--reposerver http://"
  REP_POSTFIX=":5252 "
  for server in "${rep_server[@]}"
  do
    REP_SERVER_STRING=$REP_SERVER_STRING$REP_PREFIX$server$REP_POSTFIX
  done
fi

#check if GIT_HOME exists. If not it does not make any sense to continue.
if [ ! -d "$GIT_HOME" ]; then
  echo "There seems to be something wrong. Directory $GIT_HOME not found."
  echo "Please check if you are pointing to the right directory."
  exit 1
fi

#create BSConfig.pm and change hostname to localhost
if [ ! -f $GIT_HOME/src/backend/BSConfig.pm ]; then
  cp $GIT_HOME/src/backend/BSConfig.pm.template $GIT_HOME/src/backend/BSConfig.pm
fi
perl -pi -e 's/our \$bsserviceuser.*/our \$bsserviceuser="obsrun";/' $GIT_HOME/src/backend/BSConfig.pm
perl -pi -e 's/my \$hostname.*/my \$hostname="localhost";/' $GIT_HOME/src/backend/BSConfig.pm


#start backend services (the minimum needed) with two arch(i586/x86_64) schedulers and one worker
echo "Starting bs_srcserver"
COMMAND_STRING="sudo $GIT_HOME/src/backend/bs_srcserver ${APPEND_ARR[0]} &"
eval $COMMAND_STRING
sleep 4
echo "Starting bs_repserver"
COMMAND_STRING="sudo $GIT_HOME/src/backend/bs_repserver ${APPEND_ARR[1]} &"
eval $COMMAND_STRING
sleep 2
echo "Starting bs_sched i586"
COMMAND_STRING="sudo $GIT_HOME/src/backend/bs_sched i586 ${APPEND_ARR[2]} &"
eval $COMMAND_STRING
echo "Starting bs_sched x86_64"
COMMAND_STRING="sudo $GIT_HOME/src/backend/bs_sched x86_64 ${APPEND_ARR[3]} &"
eval $COMMAND_STRING
echo "Starting bs_dispatch"
COMMAND_STRING="sudo $GIT_HOME/src/backend/bs_dispatch ${APPEND_ARR[4]} &"
eval $COMMAND_STRING
echo "Starting bs_publish"
COMMAND_STRING="sudo $GIT_HOME/src/backend/bs_publish ${APPEND_ARR[5]} &"
eval $COMMAND_STRING
echo "Starting bs_service"
COMMAND_STRING="sudo $GIT_HOME/src/backend/bs_service ${APPEND_ARR[6]} &"
eval $COMMAND_STRING
w_count=1
while [ $w_count -le $WORKER_N ]
do
  if [ ! -d /srv/obs/run/worker/$w_count ]; then
    sudo mkdir -p /srv/obs/run/worker/$w_count
  fi
  if [ ! -d /var/cache/obs/worker/root_$w_count ]; then
    sudo mkdir -p /var/cache/obs/worker/root_$w_count
  fi
  sudo chown -R obsrun:obsrun /srv/obs/run/

  index=$w_count+6;
  echo "Starting bs_worker"
 
  COMMAND_STRING="sudo $GIT_HOME/src/backend/bs_worker --hardstatus --root /var/cache/obs/worker/root_$w_count --statedir /srv/obs/run/worker/$w_count --id $HOSTNAME:$w_count $REP_SERVER_STRING --hostlabel OBS_WORKER_SECURITY_LEVEL_ --jobs 1 --cachedir /var/cache/obs/worker/cache --cachesize 3967 ${APPEND_ARR[$index]} &"
  eval $COMMAND_STRING
  let w_count=$w_count+1
done

#Cleanup function to terminate all backend services
function clean_up {
  echo -e "\ncleaning up and exit"
  echo -e "Terminating Services"
  sudo killall bs_srcserver
  echo -e "Terminated SRC Server"
  sudo killall bs_repserver
  echo -e "Terminated REP Server"
  sudo killall bs_sched
  echo -e "Terminated Scheduler"
  sudo killall bs_dispatch
  echo -e "Terminated Dispatcher"
  sudo killall bs_worker
  echo -e "Terminated Worker"
  sudo killall bs_publish
  echo -e "Terminated Publisher"
  sudo killall bs_service
  echo -e "Terminated Publisher"
  exit;
}

if [ -n "$REDIR_LOG" ]; then
  echo "Logfiles will be written to $REDIR_LOG"
  echo "Each service has it's own logfile"
fi
echo "If you want to terminate the backend, just hit Ctrl-C"

wait
