##############################################################################
#
# Copyright (c) 2003-2018 by The University of Queensland
# http://www.uq.edu.au
#
# Primary Business: Queensland, Australia
# Licensed under the Apache License, version 2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
# Development until 2012 by Earth Systems Science Computational Center (ESSCC)
# Development 2012-2013 by School of Earth Sciences
# Development from 2014 by Centre for Geoscience Computing (GeoComp)
#
##############################################################################

from __future__ import print_function, division

__copyright__="""Copyright (c) 2003-2018 by The University of Queensland
http://www.uq.edu.au
Primary Business: Queensland, Australia"""
__license__="""Licensed under the Apache License, version 2.0
http://www.apache.org/licenses/LICENSE-2.0"""
__url__="https://launchpad.net/escript-finley"



class GroupTest(object):
    _allfuncs = []

    def __init__(self, name, exec_cmd, evars, python_dir, working_dir, test_list, single_process_tests=[]):
        self.name=name
        self.python_dir=python_dir
        self.working_dir=working_dir
        self.test_list=test_list
        self.exec_cmd=exec_cmd
        self.evars=evars
        self.mkdirs=[]
        self.single_process_tests=single_process_tests
        self._allfuncs.append(name)
        
    def makeDir(self,dirname):
        self.mkdirs.append(dirname)

    #stdloc means that the files are in standard locations so don't use prefix
    def makeHeader(build_platform, prefix, stdloc):
        res="""#!/bin/sh
#############################################
# This file is autogenerated by scons.
# It will be regenerated each time scons is run
#############################################

failed () {
    echo "Execution failed for $@"
    exit 1
}

if [ $# -lt 2 ]; then
    echo "Usage: $0 build_dir wrapper_options [groupname]"
    echo Runs all or a group of unit tests. Options must be a single string.
    exit 2
fi

case "$1" in
   /*) ;;
   *) echo "build_dir needs to be an absolute path"; exit 4;;
esac

NUMPROCS=1
NUMNODES=1
while getopts ':n:p:' option $2
do
    case "$option" in
        "n")  NUMNODES=$OPTARG ;;
        "p")  NUMPROCS=$OPTARG ;;
    esac
done
MPIPROD=$(($NUMPROCS * $NUMNODES))
"""
        res+="BUILD_DIR=$1"+"/"+build_platform
        res+="\nif [ ! -d $BUILD_DIR ]\nthen\n    echo Can not find build directory $BUILD_DIR\n     exit 2\nfi\n" 
        if stdloc:
            res+="""MPITYPE=`run-escript -c | grep mpi=`
export OLD_PYTHON=$PYTHONPATH
BATCH_ROOT=`pwd`
BINRUNNER="run-escript -b $2"
PYTHONRUNNER="run-escript $2"
PYTHONTESTRUNNER="run-escript $2 $BATCH_ROOT/tools/testrunner.py"
"""
        else:
            res+="""MPITYPE=`{0}/bin/run-escript -c | grep mpi=`
BATCH_ROOT=`pwd`            
export LD_LIBRARY_PATH={0}/lib:$LD_LIBRARY_PATH
export OLD_PYTHON={0}:$PYTHONPATH
BINRUNNER="{0}/bin/run-escript -b $2"
PYTHONRUNNER="{0}/bin/run-escript $2"
PYTHONTESTRUNNER="{0}/bin/run-escript $2 {0}/tools/testrunner.py"
""".format(prefix)
        if build_platform=='darwin':
            res+="export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DYLD_LIBRARY_PATH\n"
        return res
    makeHeader=staticmethod(makeHeader)

    def makeString(self):
        res="%s () {\n"%self.name
        tt="\t"
        build_dir = self.working_dir.replace("$BATCH_ROOT", "$BUILD_DIR")
        for d in self.mkdirs:
            res=res+tt+"if [ ! -d "+str(d)+" ]\n"+tt+"then\n"+tt+"\tmkdir -p "+str(d)+"\n"+tt+"fi\n"
        for v in self.evars:
            res=res+tt+"export "+str(v[0])+"="+str(v[1])+"\n"
        res=res+tt+"if [ ! -d "+str(self.working_dir)+" ]\n"+tt+"then\n"+tt+"\tmkdir -p "+str(self.working_dir)+"\n"+tt+"fi\n"
        if len(self.python_dir)>0:
            res=res+tt+"export PYTHONPATH="+self.python_dir+":$OLD_PYTHON"+"\n"+tt+"cd "+self.working_dir+"\n"
        else:
            res=res+tt+"export PYTHONPATH=$OLD_PYTHON"+"\n"+tt+"cd "+self.working_dir+"\n"
        if len(self.single_process_tests) > 0:
            res+=tt+"if [ $MPIPROD -le 1 ]; then\n"
            #res+=tt+'if [ "$MPITYPE" == "mpi=none" ]; then\n'
            tt+="\t"
            for t in self.single_process_tests:
                res=res+tt+"echo Starting "+t+"\n"+tt+"date\n"
                skipoutputfile = ""
                failoutputfile = ""
                cmd = self.exec_cmd
                exit_on_failure = " || failed %s"%t
                if "examples" not in build_dir and "PYTHONRUNNER" in self.exec_cmd \
                        and "/tools/" not in build_dir:
                    skipoutputfile = " -skipfile={0}/{1}".format(build_dir, t.replace(".py", ".skipped"))
                    failoutputfile = " -failfile={0}/{1}".format(build_dir, t.replace(".py", ".failed"))
                    cmd = cmd.replace("PYTHONRUNNER", "PYTHONTESTRUNNER")
                res += "".join([tt, cmd, t, failoutputfile, skipoutputfile, exit_on_failure, "\n"])
                res += tt+"echo Completed "+t+"\n"
            tt="\t"
            res+=tt+"fi\n"
        for t in self.test_list:
            res=res+tt+"echo Starting "+t+"\n"+tt+"date\n"
            skipoutputfile = ""
            failoutputfile = ""
            cmd = self.exec_cmd
            exit_on_failure = " || failed %s"%t
            if "examples" not in build_dir and "PYTHONRUNNER" in self.exec_cmd \
                    and "/tools/" not in build_dir:
                skipoutputfile = " -skipfile={0}/{1}".format(build_dir, t.replace(".py", ".skipped"))
                failoutputfile = " -failfile={0}/{1}".format(build_dir, t.replace(".py", ".failed"))
                cmd = cmd.replace("PYTHONRUNNER", "PYTHONTESTRUNNER")
            res += "".join([tt, cmd, t, failoutputfile, skipoutputfile, exit_on_failure, "\n"])
            res += tt+"echo Completed "+t+"\n"
        res=res+"}\n"
        return res
    
    def makeFooter(self):
        res="if [ $# -gt 2 ]; then\n\teval $3\nelse\n\t"
        res+="\n\t".join(self._allfuncs)
        res+="\nfi\nfind $BUILD_DIR -name '*.failed' | xargs cat; find $BUILD_DIR -name '*.failed' | xargs cat | diff -q - /dev/null >/dev/null\n"
        return res

