#!/bin/sh -eu
# ###########################################################################
#             Thomas Dreibholz's R Simulation Scripts Collection
#                  Copyright (C) 2005-2025 Thomas Dreibholz
#
#               Author: Thomas Dreibholz, thomas.dreibholz@gmail.com
# ###########################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Contact: thomas.dreibholz@gmail.com


# ====== Check parameters ===================================================
if [ $# -lt 4 ] ; then
   echo >&2 "Usage: $0 [Simulation Directory] [Run Directory] [.ini File Name] [Pool Handle] {Misc Options to PU}"
   exit 1
fi
SIM_DIRECTORY="$(pwd)/$1"        # e.g.: <path>/test1
TMP_DIRECTORY="$(pwd)/$1/Temp"   # e.g.: <path>/test1/Temp
RUN_DIRECTORY="$(pwd)/$2"        # e.g.: <path>/test1/Simulations/Set-XXXX
INI_NAME="$3"                    # e.g.: run1-parameters.ini
POOLHANDLE="$4"                  # e.g.: ScriptingPool
PU_MISCOPT="$5"                  # e.g.: "-cspserver=... ..."
XML_NAME="$6"
MAX_RETRIES=10                   # After a remote-side error, retry how many times?


# ###########################################################################
# Settings for running the simulation:
#  - SIMULATION_ENVIRONMENT sets tar.bz2 file containing environment
#       (this file should contain simulation.config-stage0)
#  - SIMULATION_CONFIGS sets simulation.config-stageX files to be included
#       (ssrun will execute them in alphabetical order, beginning with stage 0)
#  - SIMULATION_POOLUSER sets the Scripting PU program (including path)
#
SIMULATION_ENVIRONMENT="simulation-environment.tar.bz2"
SIMULATION_CONFIGS=""   # "simulation.config-stage1"
SIMULATION_POOLUSER=/usr/bin/scriptingclient
# SIMULATION_POOLUSER=~/src/rsplib2/rsplib/scriptingclient
# ###########################################################################

UNIQUE_ID="$2/$INI_NAME"
PU_LOGFILE="$RUN_DIRECTORY/$INI_NAME.log"
PU_LOGLEVEL=2
VALGRIND=
#VALGRIND="valgrind  -v --tool=memcheck --leak-check=yes --show-reachable=no --leak-resolution=high --num-callers=40 --freelist-vol=4000000"
#VALGRIND="valgrind" #  -v --tool=helgrind"


# ====== Prepare temporary file names =======================================
if [ ! -e "$SIMULATION_POOLUSER" ] ; then
   echo >&2 "==================================================="
   echo >&2 "ERROR: Unable to find PU program at $SIMULATION_POOLUSER!"
   echo >&2 "==================================================="
   exit 1
fi
INPUT_ARCHIVE="$(mktemp -t -p "$TMP_DIRECTORY" input-XXXXXXXXXX)"
OUTPUT_ARCHIVE="$(mktemp -t -p "$TMP_DIRECTORY" output-XXXXXXXXXX)"


# ====== Create input archive ===============================================
echo "Preparing input [$UNIQUE_ID] ..."
# Using "nice" here, since there may be many sessions ...
# shellcheck disable=SC2086
nice tar czhf "$INPUT_ARCHIVE" \
   -C.                ssrun $SIMULATION_CONFIGS \
   -C"$RUN_DIRECTORY" "$INI_NAME" $XML_NAME


# ====== Start PU for job distribution ======================================
echo "Distributing and processing [$UNIQUE_ID] ..."
# Not using "nice" here, in order to ensure quick upload/download ...
# NOTE: At least rsplib 2.7.6 is required!
RESULT=0
# shellcheck disable=SC2086
$VALGRIND $SIMULATION_POOLUSER \
   -runid="$UNIQUE_ID" -quiet -maxretry=$MAX_RETRIES \
   -environment="$SIM_DIRECTORY/$SIMULATION_ENVIRONMENT" \
   -input="$INPUT_ARCHIVE" -output="$OUTPUT_ARCHIVE" \
   -logfile="$PU_LOGFILE" -loglevel=$PU_LOGLEVEL \
   -poolhandle="$POOLHANDLE" \
   $PU_MISCOPT || RESULT=1
# >vg$RANDOM.txt 2>&1 || RESULT=1
if [ -e "$PU_LOGFILE" ] ; then
   rm -f "$PU_LOGFILE".bz2
   bzip2 "$PU_LOGFILE"
fi


# ====== Extract results archive ============================================
echo "Extracting [$UNIQUE_ID] ..."
cd "$RUN_DIRECTORY"
if [ ! -s "$OUTPUT_ARCHIVE" ] ; then
   echo >&2 "==================================================="
   echo >&2 "ERROR: No results have been created in directory $RUN_DIRECTORY!"
   echo >&2 "==================================================="
   exit 1
fi

# Using "nice" here, since there may be many sessions ...
nice tar xzhvf "$OUTPUT_ARCHIVE" | xargs touch   # This will also update the time stamp!
rm -f "$INPUT_ARCHIVE" "$OUTPUT_ARCHIVE"

# Print error, if run has not been completed successfully ...
if [ $RESULT -ne 0 ] ; then
   echo ""
   echo "----- SIMULATION RUN FAILED -----"
   echo ""

   OUTPUT_NAME=$(echo "$INI_NAME" | sed -e "s/-parameters.ini$/-output.txt.bz2/g")
   if [ -e "$RUN_DIRECTORY/$OUTPUT_NAME" ] ; then
      echo "#########################################################"
      bzgrep "^<\!> Error " "$RUN_DIRECTORY/$OUTPUT_NAME"
      echo "#########################################################"
      echo ""
   fi

   echo "INI file:    $RUN_DIRECTORY/$INI_NAME"
   echo "Output file: $RUN_DIRECTORY/$OUTPUT_NAME"
   echo "----- SIMULATION RUN FAILED -----"
fi

exit $RESULT
