#!/bin/bash
#---------------------------------*- sh -*-------------------------------------
# ==  == ====== ====   ====    |
#                   \\     ||  | Multiphase Code Repository by HZDR
# ======   //   ||  || ===//   | Website: https://doi.org/10.14278/rodare.767
# ||  ||  //    ||  // || \\   | License: GPL-3.0-or-later
# ==  == ====== ====   ==  ==  |
#------------------------------------------------------------------------------
# License
#     This file is part of the Multiphase Code Repository by HZDR.
#
#     Copyright (C) 2025 by Helmholtz-Zentrum Dresden-Rossendorf e.V. (HZDR),
#     Website: https://hzdr.de
#
#     Multiphase Code Repository by HZDR is based on the free software for
#     computational fluid dynamics (CFD) from the OpenFOAM Foundation.
#     Copyright (C) 2025 by OpenFOAM Foundation, Website: https://openfoam.org
#
#     If you are interested in which files are original OpenFOAM Foundation
#     files, which OpenFOAM Foundation files were modified, and which files were
#     newly created, see FILES.md.
#
#     Multiphase Code Repository by HZDR 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.
#
#     Multiphase Code Repository by HZDR 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 the Multiphase Code Repository by HZDR. If not, see
#     <http://www.gnu.org/licenses/>.
#
# Script
#     Allrun
#
# Description
#     Runs the OpenFOAM tutorials or tests by using foamRunTutorials. The log
#     files generated within each directory are analysed for OpenFOAM errors and
#     a XML report according to jUnit format is produced as a summary. The jUnit
#     format is processed by GitLab automatically. For local usage use
#
#     pip install junit2html
#     junit2html report.xml report.html
#
#     to create a html report file that is human readable with a browser.
#
#------------------------------------------------------------------------------
cd ${0%/*} || exit 1    # Run from this directory

usage()
{
    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
    cat<<USAGE

usage: ${0##*/} [OPTION]

options:
  -report           skip run step and generate report
  -help             print the usage

* runs the OpenFOAM tutorials or tests and generates an XML report

USAGE
    exit 1
}

#------------------------------------------------------------------------------

# Source run functions
. $WM_PROJECT_SITE/$WM_PROJECT_VERSION/bin/tools/RunFunctions

suiteName="Multiphase Code Repository by HZDR for OpenFOAM Foundation Software"
shortName="addon"
workDir=$(dirname ${PWD})
testDir=$(basename ${PWD})
suiteDir=$(basename ${PWD%%Test})
xmlFile="report.xml"

report=""

# Parse options
while [ "$#" -gt 0 ]
do
    case "$1" in
    -report)
        report="true"
        ;;
    -h | -help)
        usage
        ;;
    -*)
        usage "unknown option: '$*'"
        ;;
    *)
        usage "unknown option/argument: '$*'"
        ;;
    esac
    shift
done

# writeXMLHeader <Tests> <Failures> <Skipped> <Execution Time>
writeXMLHeader()
{
date=$(date)

cat<<EOF>>$xmlFile
<?xml version="1.0" encoding="UTF-8" ?>
<testsuites id="$shortName" name="$suiteName" tests="$1" failures="$2" skipped="$3" time="$4">
<testsuite id="$shortName.$suiteDir" name="$suiteDir at $date" tests="$1" failures="$2" skipped="$3" time="$4">
EOF
}

# Function to write xml footer
writeXMLFooter()
{
cat<<EOF>>$xmlFile
</testsuite>
</testsuites>
EOF
}

# Function to remove template case sub-folders from path by checking
# if directory exists in suiteDir
templateDir()
{
    d="$1"
    while [ "$d" != "." ]
    do
        if [ -d "$workDir/$suiteDir/$d" ]; then break; fi
        d=$(dirname "$d")
    done
    echo "$suiteDir/$d"
}

# logReport <logfile>
# Extracts useful info from log file
logReport()
{
    fatalError=`grep "FOAM FATAL" $1`
    UxSS=`grep -E "Ux[:| ]*solution singularity" $1`
    UySS=`grep -E "Uy[:| ]*solution singularity" $1`
    UzSS=`grep -E "Uz[:| ]*solution singularity" $1`
    gnuplotWarning=`grep -E "warning: Cannot find or open file" $1`
    completed=`grep -E "^[\t ]*[eE]nd" $1`

    if [ "$fatalError" ]
    then
        echo "time=\"0\">"
        echo "<failure>FOAM_FATAL_ERROR</failure>"
        return 1
    elif [ "$UxSS" -a "$UySS" -a "$UzSS" ]
    then
        echo "time=\"0\">"
        echo "<failure>Solution singularity</failure>"
        return 1
    elif [ "$gnuplotWarning" ]
    then
        echo "time=\"0\">"
        echo "<failure>Gnuplot warning</failure>"
        return 1
    elif [ "$completed" ]
    then
        completionTime=`grep Execution $1 | tail -n 1 | cut -d= -f2 | sed 's/^[ \t]*//' | cut -d\  -f1`
        if [ "$completionTime" ]
        then
            echo "time=\"$completionTime\">"
        else
            echo "time=\"0\">"
        fi
        return 0
    else
        echo "time=\"0\">"
        echo "<failure>unconfirmed completion</failure>"
        return 1
    fi
}


# logReportDir <directory>
# Extracts useful info from all log files in a directory
logReportDir()
(
    [ -d $1 ] || return 0

    cd $1 || return 1

    logs=`find . -name "log.*" ! -name "log.foamDictionary"`
    [ -n "$logs" ] || return 0

    retVal=0

    for log in `echo $logs | xargs ls -rt`
    do
        caseName=`dirname $log | sed s/"\(.*\)\.\/"/""/g`
        app=`echo $log | sed s/"\(.*\)log\."/""/g | sed s/"\.txt\(.*\)"/""/g`
        fileDir=$(templateDir "$1/$caseName")
        echo -n "<testcase id=\"$shortName.$suiteDir\" classname=\"$caseName\" name=\"$app\" file=\"$fileDir\" " >> ../$xmlFile
        logReport $log >> ../$xmlFile || retVal=1
        echo "<system-out>[[ATTACHMENT|$testDir/$1/$log]]</system-out>" >> ../$xmlFile
        echo "</testcase>" >> ../$xmlFile
    done

    return $retVal
)


# Recursively run all cases
if [ ! "$report" ]
then
    start=$(date +%s.%N)
    foamRunTutorials -test -skipFirst
    exectime=$(echo "$(date +%s.%N) - $start" | bc)
fi

# Collect summary from log files
nTests=`find . -name "log.*" ! -name "log.foamDictionary" | wc -l`
nFailures=`find . -name "log.*" ! -name "log.foamDictionary" -exec grep "FOAM_FATAL" {} \; | wc -l`
nCompleted=`find . -name "log.*" ! -name "log.foamDictionary" -exec grep -E -l "^[\t ]*[eE]nd" {} \; | wc -l`
nSkipped=$(echo "$nTests - $nCompleted - $nFailures" | bc)

# Analyse all log files
rm -f $xmlFile && touch $xmlFile
writeXMLHeader $nTests $nFailures $nSkipped $exectime

retVal=0

for appDir in *
do
    logReportDir $appDir || retVal=1
done

writeXMLFooter

exit $retVal

#------------------------------------------------------------------------------
