#!/bin/bash
set -fe -o pipefail

PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE:-python2.7}

if [ $# -lt 2 ]; then
    echo "Usage ./test install_folder hysop_folder [cache_dir] [backup_cache_dir]"
    exit 1
fi

if [ $# -gt 4 ]; then
    echo "Usage ./test install_folder hysop_folder [cache_dir] [backup_cache_dir]"
    exit 1
fi

if [ ! -d "$1" ]; then
    echo "Folder $1 does not exist."
    exit 1
fi

if [ ! -d "$2" ]; then
    echo "Folder $2 does not exist."
    exit 1
fi

INSTALL_DIR="$1"
HYSOP_DIR="$2"

if [ $# -gt 2 ]; then
    CACHE_DIR="$3"
    HAS_CACHE_DIR=true
else
    HAS_CACHE_DIR=false
fi

if [ $# -gt 3 ]; then
    BACKUP_CACHE_DIR="$4"
fi

if [ "${HAS_CACHE_DIR}" = true ]; then
    mkdir -p "${HOME}/cache"
    if [ -d "${CACHE_DIR}" ]; then
        echo "Cache directory '$CACHE_DIR' was found."
        cp -r $CACHE_DIR/* "${HOME}/.cache"
    else
        # Untill gitlab allows cache on failure we need
        # to provide initial cache so that CI succeeds (< 1h tests)
        # see https://gitlab.com/gitlab-org/gitlab/-/issues/18969
        # Initial cache will be builtin in the docker image.
        echo "Cache directory '$CACHE_DIR' was not found."
        if [[ -d "${BACKUP_CACHE_DIR}" ]]; then
            echo "Backup cache directory '${BACKUP_CACHE_DIR}' was found."
            cp -r ${BACKUP_CACHE_DIR}/* "${HOME}/.cache"
        elif [[ -z "${BACKUP_CACHE_DIR}" ]]; then
            echo "No backup cache directory has been specified."
        else
            echo "Backup directory '${BACKUP_CACHE_DIR}' was not found."
        fi
    fi
fi
mkdir -p "${HOME}/.cache"
mkdir -p "${CACHE_DIR}"

export PYTHONPATH="$INSTALL_DIR/lib/python2.7/site-packages:$INSTALL_DIR:$PYTHONPATH"
export MPLBACKEND='cairo'
export HYSOP_VERBOSE=0
export HYSOP_DEBUG=0
export HYSOP_PROFILE=0
export HYSOP_KERNEL_DEBUG=0

# OpenMPI specific variables
export OMPI_ALLOW_RUN_AS_ROOT=1
export OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1
export OMPI_MCA_rmaps_base_oversubscribe=1

echo "Trying to load hysop module:"
${PYTHON_EXECUTABLE} -c 'import hysop; print hysop'
echo "module import successful !"
echo

echo "Default testing OpenCL platform is:"
${PYTHON_EXECUTABLE} -c 'import hysop; from hysop.testsenv import iter_clenv; print next(iter(iter_clenv()));'

RUN_TESTS=${RUN_TESTS:-true}
RUN_EXAMPLES=${RUN_EXAMPLES:-false}
RUN_LONG_TESTS=${RUN_LONG_TESTS:-false}

COMMON_TEST_OPTIONS=''
TEST_DIR="$HYSOP_DIR"
COMMON_EXAMPLE_OPTIONS='-VNC -d16 -cp default -maxit 2'
EXAMPLE_DIR="$HYSOP_DIR/../hysop_examples/examples"

hysop_test() {
     test=$1
     echo 
     echo "TESTING $1"
     echo "========$(printf '=%.0s' `seq ${#1}`)"
     ${PYTHON_EXECUTABLE} "${TEST_DIR}/${1}" ${@:2} ${COMMON_TEST_OPTIONS} 
     echo
}
example_test() {
     test=$1
     echo 
     echo "EXAMPLE $1"
     echo "========$(printf '=%.0s' `seq ${#1}`)"
     ${PYTHON_EXECUTABLE} "${EXAMPLE_DIR}/${1}" ${@:2} ${COMMON_EXAMPLE_OPTIONS}
     echo
}

if [ "$RUN_TESTS" = true ]; then
    hysop_test "core/arrays/tests/test_array.py"
    hysop_test "core/graph/tests/test_graph.py"
    hysop_test "fields/tests/test_fields.py"
    hysop_test "numerics/tests/test_fft.py"
    hysop_test "operator/tests/test_analytic.py"
    hysop_test "operator/tests/test_transpose.py"
    hysop_test "operator/tests/test_fd_derivative.py"
    hysop_test "operator/tests/test_absorption.py"
    hysop_test "operator/tests/test_penalization.py"
    hysop_test "operator/tests/test_velocity_correction.py"
    hysop_test "operator/tests/test_restriction_filter.py"
    hysop_test "operator/tests/test_directional_advection.py"
    hysop_test "operator/tests/test_directional_diffusion.py"
    hysop_test "operator/tests/test_directional_stretching.py"
    hysop_test "operator/tests/test_custom_symbolic.py"
    hysop_test "operator/tests/test_spectral_derivative.py"
    hysop_test "operator/tests/test_spectral_curl.py"
    hysop_test "operator/tests/test_diffusion.py"
    hysop_test "operator/tests/test_poisson.py"
    hysop_test "operator/tests/test_solenoidal_projection.py"
    hysop_test "operator/tests/test_poisson_curl.py"
    $HYSOP_DIR/fields/tests/test_cartesian.sh
fi

if [ "$RUN_LONG_TESTS" = true ]; then
    hysop_test "backend/device/codegen/kernels/tests/test_directional_advection.py"
    hysop_test "backend/device/codegen/kernels/tests/test_directional_remesh.py"
fi

if [ "$RUN_EXAMPLES" = true ]; then
    example_test "analytic/analytic.py"
    example_test "scalar_diffusion/scalar_diffusion.py"
    example_test "scalar_advection/scalar_advection.py"
    example_test "scalar_advection/levelset.py"
    example_test "multiresolution/scalar_advection.py"
    example_test "shear_layer/shear_layer.py"
    example_test "taylor_green/taylor_green.py" '-impl python'
    example_test "taylor_green/taylor_green.py" '-impl opencl'
    example_test "bubble/periodic_bubble.py"
    example_test "bubble/periodic_bubble_levelset.py"
    #example_test "bubble/periodic_bubble_levelset_penalization.py" #LLVM bug for DP
    example_test "bubble/periodic_jet_levelset.py"
    example_test "particles_above_salt/particles_above_salt_periodic.py"
    example_test "particles_above_salt/particles_above_salt_symmetrized.py"
fi

if [ "$HAS_CACHE_DIR" = true ]; then
    cp -r ${USER}/.cache/* $CACHE_DIR
    find "${CACHE_DIR}" -name '*.lock' -delete
fi

exit 0