#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Script "launch.py": aide au lancement d'un job Metafor

import sys, os, os.path, subprocess
import shutil, socket, platform, glob, fnmatch, re
import datetime, tarfile, signal

from parametricJob import *
from subprocess import *   # RB subprocess deja importe + haut??

class LaunchJob(ParametricJob):
    def __init__(self, _jobId=''):
        self.debug = False
        self.jobId=_jobId
        cfgfile="launch%s.cfg"%self.jobId
        ParametricJob.__init__(self, cfgfile)
        # gestion des dépendances entre paramètres 
        self.applyDependencies()
        # liens vers launchGui (lorsque lancé par ce biais pour interaction)
        self.launchGui = None
        self.outFile   = None

    def setLaunchGui(self, launchGui):
        self.launchGui = launchGui

    def setDefaultPars(self):
        if len(self.pars)!=0:
            return
        YesNoPRM(self.pars, 'SEND_MAIL',    'send emails when simulations are over', False)
        TextPRM(self.pars,  'MAIL_ADDR',    'e-mail address (reports)', os.getenv('USER'))
        TextPRM(self.pars,  'SMTP_SERV',    'SMTP email server', 'smtp.ulg.ac.be')

        TextPRM(self.pars,  'PYTHONEXE',    'Python executable', sys.executable) 
        mtfExe = os.path.abspath(os.path.dirname(__file__))+os.sep+'Metafor'
        if (not isUnix()):
            mtfExe = mtfExe+'.exe'

        TextPRM(self.pars,  'EXEC_NAME',    'exec name',  mtfExe)
        TextPRM(self.pars,  'TEST_NAME',    'test filename', './mesTests/monTest.py')
        TextPRM(self.pars,  'TEST_DIR',     'test dir for multi', './mesTests/')
        TextPRM(self.pars,  'OUTFILE',      'logfile (no ext)', 'out')

        YesNoPRM(self.pars, 'MULTITEST',    'Run multiple test on dir', False)
        MultiPRM(self.pars, 'ALGORITHM',    'algorithm', ["meta", "import", "execfile", "clean", "verif", "restart"], "meta")

        TextPRM(self.pars,  'RESTART_STEP', 'restart step', "-1")

        TextPRM(self.pars,  'PRIORITY',     'priority [1-5]', "3")
        TextPRM(self.pars,  'AFFINITY',     'affinity (cores list)', "")
        TextPRM(self.pars,  'NB_TASKS',     'nb of task launched in parallel', "1")
        TextPRM(self.pars,  'NB_THREADS',   'nb of threads by task', "1")
        # Run Method : 
        MultiPRM(self.pars, 'RUNMETHOD',    'Run Method', ["interactive", "at", "batch", "slurm", "sge", "pbs"], "interactive")
        #AT
        TextPRM(self.pars,  'AT_TIME' ,     'Delay for at launch (no syntax check, use with care)', "now")
        # QUEUING SYSTEMS : SGE / SLURM
        TextPRM(self.pars,  'QUEUE',        'Queue name', "defq")
        YesNoPRM(self.pars, 'LOCALDISK',    'Metafor run on node local disk', True)
        TextPRM(self.pars,  'MEMORY',       'Total Memory (Mb)', "1000")
        TextPRM(self.pars,  'TIME',         'Time (slurm : d-hh:mm:ss / PBS : d:hh:mm:ss) ', "0-1:00:00")
        # SGE specific
        TextPRM(self.pars,  'SGE_PE',       'SGE parallel environment', "snode")
        TextPRM(self.pars,  'SGEARGS',      'additional SGE args', "")
        # PBS Specific (zenobe)       
        #TextPRM(self.pars,  'QUEUE',       'PBS Queue name', "main") # zenobe : main ou large
        TextPRM(self.pars,  'PROJECT',      'Project Name (Acces group dirs)', "hpcwe")
        MultiPRM(self.pars, 'MODEL',        'CPU Model', ["auto", "westemere", "westmere_fat", "westmere_xfat", "ivyBridge", "haswell_xfat"], "auto")
        
        # FTP
        YesNoPRM(self.pars, 'ENABLE_FTP',   'ftp transfert', False)
        TextPRM(self.pars,  'FTP_HOST',     'ftp host', "")
        TextPRM(self.pars,  'FTP_PORT',     'ftp port', "21")
        TextPRM(self.pars,  'FTP_USER',     'ftp user', "")
        TextPRM(self.pars,  'FTP_PASS',     'ftp passwd', "")
        TextPRM(self.pars,  'FTP_DIR',      'ftp directory', "incoming")

        # Actions
        PRMAction(self.actions, 'a', self.pars['MAIL_ADDR'])
        PRMAction(self.actions, 'b', self.pars['PYTHONEXE'])
        PRMAction(self.actions, 'c', self.pars['EXEC_NAME'])
        PRMAction(self.actions, 'd', self.pars['TEST_NAME'])
        PRMAction(self.actions, 'd', self.pars['TEST_DIR'])
        PRMAction(self.actions, 'e', self.pars['OUTFILE'])

        PRMAction(self.actions, 'f', self.pars['ALGORITHM'])
        PRMAction(self.actions, 'g', self.pars['RESTART_STEP'])
        PRMAction(self.actions, 'h', self.pars['MULTITEST'])

        PRMAction(self.actions, 'i', self.pars['PRIORITY'])
        PRMAction(self.actions, 'j', self.pars['AFFINITY'])
        PRMAction(self.actions, 'k', self.pars['NB_TASKS'])
        PRMAction(self.actions, 'l', self.pars['NB_THREADS'])
        PRMAction(self.actions, 'm', self.pars['RUNMETHOD'])
        # At parameters
        PRMAction(self.actions, 'n', self.pars['AT_TIME'])
        # SGE/SLURM/PBS PARAMETERS
        PRMAction(self.actions, 'n', self.pars['QUEUE'])
        PRMAction(self.actions, 'o', self.pars['LOCALDISK'])
        PRMAction(self.actions, 'p', self.pars['MEMORY'])
        PRMAction(self.actions, 'q', self.pars['TIME'])
        # SGE specific PARAMETERS
        #PRMAction(self.actions, 'n', self.pars['SGEQUEUE'])
        PRMAction(self.actions, 'r', self.pars['SGE_PE'])
        PRMAction(self.actions, 's', self.pars['SGEARGS'])
        # PBS (zenobe) specific PARAMETERS        
        PRMAction(self.actions, 'r', self.pars['PROJECT'])
        PRMAction(self.actions, 's', self.pars['MODEL'])
        
        # FTP
        PRMAction(self.actions, 'u', self.pars['ENABLE_FTP'])
        PRMAction(self.actions, 'v', self.pars['FTP_HOST'])
        PRMAction(self.actions, 'w', self.pars['FTP_PORT'])
        PRMAction(self.actions, 'x', self.pars['FTP_USER'])
        PRMAction(self.actions, 'y', self.pars['FTP_PASS'])
        PRMAction(self.actions, 'z', self.pars['FTP_DIR'])

        # Actions
        NoAction(self.actions)
        GoAction(self.actions,    'G')
        SaveAction(self.actions,  'S')
        QuitAction(self.actions,  'Q')

    def applyDependencies(self):
        ret = False
        if self.debug:
            print("applyDependecies: ")
            print("     self.pars['ALGORITHM'].val = ", self.pars['ALGORITHM'].val)

        #if self.pars['ALGORITHM'].val=='restart':
        #    self.pars['MULTITEST'].val = False
        #    ret = True

        if self.debug:
            print("     self.pars['MULTITEST'].val = ", self.pars['MULTITEST'].val)
        return ret

    def configActions(self):
        #self.pars['MAIL_ADDR'].enable(self.pars['SEND_MAIL'].val==True or 
        #                              self.pars['RUNMETHOD'].val=='sge' or
        #                              self.pars['RUNMETHOD'].val=='slurm' or
        #                              self.pars['RUNMETHOD'].val=='pbs')
        self.pars['SMTP_SERV'].enable(self.pars['SEND_MAIL'].val==True)

        self.pars['TEST_NAME'].enable(self.pars['MULTITEST'].val==False)
        self.pars['TEST_DIR'].enable(self.pars['MULTITEST'].val==True)

        self.pars['RESTART_STEP'].enable(self.pars['ALGORITHM'].val=='restart' and
                                         self.pars['MULTITEST'].val==False)

        self.pars['FTP_HOST'].enable(self.pars['ENABLE_FTP'].val==True)
        self.pars['FTP_PORT'].enable(self.pars['ENABLE_FTP'].val==True)
        self.pars['FTP_USER'].enable(self.pars['ENABLE_FTP'].val==True)
        self.pars['FTP_PASS'].enable(self.pars['ENABLE_FTP'].val==True)
        self.pars['FTP_DIR'].enable(self.pars['ENABLE_FTP'].val==True)

        self.pars['PRIORITY'].enable(self.pars['RUNMETHOD'].val!='sge' and
                                     self.pars['RUNMETHOD'].val!='slurm')

        self.pars['AFFINITY'].enable(self.pars['RUNMETHOD'].val!='sge' and
                                     self.pars['RUNMETHOD'].val!='slurm' and
                                     self.pars['MULTITEST'].val==False)
        # At
        self.pars['AT_TIME'].enable(self.pars['RUNMETHOD'].val=='at')
        # SGE/SLURM/PBS
        self.pars['QUEUE'].enable(self.pars['RUNMETHOD'].val=='sge' or
                                  self.pars['RUNMETHOD'].val=='slurm' or
                                  self.pars['RUNMETHOD'].val=='pbs')
        self.pars['LOCALDISK'].enable((self.pars['RUNMETHOD'].val=='sge' or
                                       self.pars['RUNMETHOD'].val=='slurm') and # pas zenobe
                                      self.pars['ALGORITHM'].val!='restart' )
        self.pars['TIME'].enable(self.pars['RUNMETHOD'].val=='sge' or
                                 self.pars['RUNMETHOD'].val=='slurm' or
                                  self.pars['RUNMETHOD'].val=='pbs')
        self.pars['MEMORY'].enable(self.pars['RUNMETHOD'].val=='sge' or
                                   self.pars['RUNMETHOD'].val=='slurm' or
                                  self.pars['RUNMETHOD'].val=='pbs')
        # SGE specific
        self.pars['SGE_PE'].enable(self.pars['RUNMETHOD'].val=='sge')
        self.pars['SGEARGS'].enable(self.pars['RUNMETHOD'].val=='sge')

        # PBS specific
        self.pars['MODEL'].enable(self.pars['RUNMETHOD'].val=='pbs') # cpu model (to choose subqueue)
        self.pars['PROJECT'].enable(self.pars['RUNMETHOD'].val=='pbs') # project (group access & facturation)

    def getJobName(self):
        if (self.pars['MULTITEST'].val==False):
            jobname=os.path.basename(os.getcwd())+"."+self.pars['TEST_NAME'].val
        else:
            jobname=os.path.basename(os.getcwd())+"."+self.pars['TEST_DIR'].val

        jobname=jobname.replace(os.sep,'.')
        jobname=jobname.replace('.py','')
        jobname=jobname.replace('...','.')
        jobname=jobname.replace('..','.')
        if jobname.endswith('.'):
            jobname=jobname[:-1]
        return jobname.encode('ascii','ignore') # convert to ASCII if some strings were unicode

    def getOutFileName(self):
        outFileName  = "%s.%s%s.txt" % (self.pars['OUTFILE'].val, self.pars['ALGORITHM'].val,self.jobId)
        if self.debug:
            print("outFileName = ", outFileName)
        return outFileName

    # RUN Functions
    def run(self):
        # deactivate use of LocalDisk in restart
        if (self.pars['ALGORITHM'].val == "restart" ):
            self.pars['LOCALDISK'].val = False
        # write kill scripts
        if isUnix():
            if (self.pars['RUNMETHOD'].val == 'interactive' or self.pars['RUNMETHOD'].val == 'at' or
                self.pars['RUNMETHOD'].val == 'batch'):
                self.killScript(self.jobId, os.getpgrp())
            elif ((self.pars['RUNMETHOD'].val == 'sge' or self.pars['RUNMETHOD'].val == 'slurm') and
                  self.pars['LOCALDISK'].val == True):
                self.cpNodeResultsScript(self.jobId)
                self.rmNodeResultsScript(self.jobId)
        # check exec
        if not os.path.isfile(self.pars['EXEC_NAME'].val):
            self.error("Metafor executable not found at %s" % self.pars['EXEC_NAME'].val)
        # add __init__.py
        if not os.path.isfile("__init__.py"):
            file = open("__init__.py","w")
            file.close()

        # starts  tests
        if (self.pars['MULTITEST'].val==True):
            #check
            if not os.path.isdir(self.pars['TEST_DIR'].val):
                print("Error: 'TEST_DIR' %s non existant directory" % self.pars['TEST_DIR'].val)
                return
            #asciiname = self.pars['TEST_DIR'].val.encode('ascii','ignore') # convert unicode (from PyQt)
            #outRun = self.startMultipleTests(asciiname)
            outRun = self.startMultipleTests(self.pars['TEST_DIR'].val)
        else:
            #check
            if not os.path.isfile(self.pars['TEST_NAME'].val):
                print("Error: 'TEST_NAME' %s non existant file" % self.pars['TEST_NAME'].val)
                return
            #run
            #asciiname = self.pars['TEST_NAME'].val #.encode('ascii','ignore') # convert unicode (from PyQt)
            #outRun = self.startMultipleTests(asciiname)
            outRun = self.startMultipleTests(self.pars['TEST_NAME'].val)
            '''
            if (self.pars['ALGORITHM'].val == "restart" && self.pars['RESTART_STEP'].val > 0):
                outRun = self.startSingleTest()
            else:
                outRun = self.startMultipleTests(self.pars['TEST_NAME'].val)
            '''
        if self.pars['ENABLE_FTP'].val==True:
            #tar facs
            cdir=os.path.basename(os.getcwd())
            tarname="%s.tar.gz" % cdir
            print("creating %s" % tarname)
            os.chdir('..')
            tar = tarfile.open(tarname,'w:gz')
            for path, dirs, files in os.walk(cdir):
                for file in files:
                    tar.add(os.path.join(path,file))
            tar.close()

            #ftp
            print("sending results to %s" % self.pars['FTP_HOST'].val)
            import ftplib
            ftp = ftplib.FTP()
            ftp.connect(self.pars['FTP_HOST'].val, self.pars['FTP_PORT'].val)
            ftp.login(self.pars['FTP_USER'].val, self.pars['FTP_PASS'].val)
            ftp.cwd(self.pars['FTP_DIR'].val)
            file = open(tarname,'r')
            ftp.storbinary('STOR %s' %tarname, file)
            file.close()
            ftp.quit()

            #clean
            os.remove(tarname)

        # remove kill scripts
        if isUnix():
            fNames = []
            if self.pars['RUNMETHOD'].val == 'sge':
                fNames.append(self.qDelScriptName(self.jobId))
                #fNames.append(self.cfgfile)
            elif self.pars['RUNMETHOD'].val == 'slurm':
                fNames.append(self.sCancelScriptName(self.jobId))
                #fNames.append(self.cfgfile)
            elif self.pars['RUNMETHOD'].val == 'at' or self.pars['RUNMETHOD'].val == 'batch':
                fNames.append("kill%s.py"%self.jobId)
                fNames.append("atrm%s.py"%self.jobId)
                fNames.append("runbatch%s.sh"%self.jobId)
                #fNames.append(self.cfgfile)
            else:
                fNames.append("kill%s.py"%self.jobId)
            for fil in fNames:
                if os.path.isfile(fil):
                    os.remove(fil)
        print("done.")

    def startMultipleTests(self, tests):
        print("startMultipleTests")
        # starting timer
        now = datetime.datetime.now()
        print("starting Multiple test at %s (come back later)" % now.ctime())

        # opening outfile
        self.outFile   = open(self.getOutFileName(),"w")        
        mtfdir, mtfexe = os.path.split(self.pars['EXEC_NAME'].val)
        #mtfdir, mtfexe = os.path.split(self.pars['EXEC_NAME'].val.encode('ascii','ignore'))
        mtfdir = os.path.abspath(mtfdir) # necessaire pour sge sinon, en local disk, soucis pour trouver libGen4.so
        # starting python battery
        if self.launchGui:
            #self.launchGui.outFile=outfile
            # starting process (unable to renice it => nice in battery)
            prog = self.pars['PYTHONEXE'].val
            # python args -u : unbuffered output (to have output synchronized to output)
            #             -i : force a prompt event even if stdin is not a terminal (else it is not possible to write cmds to python)
            arg = ['-u', '-i']
            self.launchGui.process.start(prog, arg)
            self.launchGui.process.waitForStarted(-1)
            # defining the input flux
            pin = self.launchGui.process
        else:
            #cmd = self.getNiceCmd(int(self.pars['NICE_VALUE'].val))
            #cmd = cmd + ['python']
            cmd = [self.pars['PYTHONEXE'].val]
            if isUnix(): # shell=False  && sans close_fds = True (ca freeze)
                #Add mtfdir to LD_LIBRARY_PATH to allow launch to find mt*.so
                if 'LD_LIBRARY_PATH' in os.environ:
                    os.environ['LD_LIBRARY_PATH'] = mtfdir+':'+os.environ['LD_LIBRARY_PATH']
                else:
                    os.environ['LD_LIBRARY_PATH'] = mtfdir
                #self.outFile.write("LD_LIBRARY_PATH = %s"%os.environ['LD_LIBRARY_PATH'])
                p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=self.outFile, stderr=self.outFile, env=os.environ, shell=False, close_fds=True)
            else: # si nice+Windows => "shell=True" (pour "start")
                p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=self.outFile, stderr=self.outFile, env=os.environ, shell=True)
            # defining the input flux
            pin = p.stdin

        # filling command to battery
        pin.write(b'import sys, os, os.path\n')
        if self.debug:
            pin.write(b'print ("sys.path = ", sys.path)\n')
            pin.write(b'print ("os.getcwd() = ", os.getcwd())\n')
        pin.write(('if os.path.isdir(r"%s"):\n'%mtfdir).encode('utf-8'))
        pin.write(('\tsys.path.append(r"%s")\n'%mtfdir).encode('utf-8')) # mtfdir est dorenavant un abspath
        pin.write(b'else:\n')
        pin.write(('\tprint ("metafor dir %s not found!")\n'%mtfdir).encode('utf-8'))
        pin.write(b'\tsys.exit()\n\n')
        pin.write(('exec(open(r"%s").read())\n'%os.path.join(mtfdir,'.pythonrc.py')).encode('utf-8'))
        pin.write(b'import toolbox.battery as b\n')
        pin.write(b'battery = b.Battery() \n')
        pin.write(b'battery.keepFacs = True\n')
        pin.write(('battery.dirs = [r"%s"]\n'%tests).encode('utf-8'))
        pin.write(('battery.jobId = r"%s"\n'%self.jobId).encode('utf-8'))

        if (self.pars['ALGORITHM'].val == "execfile"):
            reg1=r"(.+)_0*([1-9][0-9]*)\.py"
            exp1= re.compile(reg1)
            m = exp1.match(os.path.basename(tests))
            if m: # chaining tests
                pin.write(('battery.addCplxExecPath(r"%s_*")\n'%os.path.join(os.path.dirname(tests), m.group(1))).encode('utf-8'))
                print('battery.cplx_exec = [r"%s_*"]\n'%os.path.join(os.path.dirname(tests), m.group(1)))
            else:
                pin.write(('battery.addCplxExecPath(r"%s")\n'%tests).encode('utf-8'))
                print('battery.cplx_exec = [r"%s"]\n'%tests)
        elif (self.pars['ALGORITHM'].val == "import" ):
            pin.write(('battery.addCplxImportPath(r"%s")\n'%tests).encode('utf-8'))
            print('battery.cplx_import = [r"%s"]\n'%tests)
        elif (self.pars['ALGORITHM'].val == "restart" ):
            pin.write(('battery.addRestartPath(r"%s")\n'%tests).encode('utf-8'))
            print('battery.restart = [r"%s"]\n'%tests)

        pin.write(b'battery.verifsrc  = "verif"\n')
        pin.write(b'battery.codes = [ "FAILED", "STP", "ITE", "INW", "EXT", "EXW", "LKS", "CPU", "MEM" ]\n')

        if ((self.pars['RUNMETHOD'].val == 'sge' or self.pars['RUNMETHOD'].val == 'slurm') and
                               self.pars['LOCALDISK'].val == True):
            pin.write(('battery.setWDRoot("%s")\n'%self.getLocalDiskDir(self.jobId)).encode('utf-8'))

        if self.pars['RUNMETHOD'].val != 'sge' and self.pars['RUNMETHOD'].val != 'slurm':
            if self.pars['AFFINITY'].val != '':
                pin.write(('battery.setAffinity("%s")\n'%self.pars['AFFINITY'].val).encode('utf-8'))
            pin.write(('battery.setPriority(%s)\n'%self.pars['PRIORITY'].val).encode('utf-8'))

        pin.write(('battery.setNumTasks(%s)\n'%self.pars['NB_TASKS'].val).encode('utf-8'))
        pin.write(('battery.setNumThreads(%s)\n'%self.pars['NB_THREADS'].val).encode('utf-8'))
        pin.write(('battery.mtfdir = r"%s"\n'%mtfdir).encode('utf-8'))
        if self.pars['ALGORITHM'].val == 'clean':
            pin.write(b'battery.start("clean")\n')
        elif self.pars['ALGORITHM'].val == 'verif':
            pin.write(b'battery.verif()\n')
        else:
            pin.write(b'battery.start("run")\n')
        #pin.write('battery.verif()\n') # pas très utile dans le cadre de launch ou faudrait faire un verif + malin)
        # write to exit python at the end of job
        pin.write(b'quit()\n')

        # wait for process to finish
        if self.launchGui:
            retcode = self.launchGui.waitQProcessForFinish()
            #print ("Qprocess finished with retcode: ",retcode)
        else:
            #close pin flux
            pin.close()
            # flush des outfile pour déjà avoir un max d'info de debug
            self.outFile.flush()
            # waiting execution time
            retcode = p.wait()

        # closing file
        self.outFile.flush()
        self.outFile.close()
        self.outFile = None

        # post pro cmd
        if ((self.pars['RUNMETHOD'].val == 'sge' or self.pars['RUNMETHOD'].val == 'slurm') and
                  self.pars['LOCALDISK'].val == True):
            print("Trying to get back local workspace to home")
            self.moveLocalDir2Home(self.jobId)

        now = datetime.datetime.now()
        print("battery completed at %s" % now.ctime())
        if self.pars['SEND_MAIL'].val == True:
            self.mailmsg("multipleTests complete", file=self.getOutFileName())
        return retcode
'''
    def startSingleTest(self):
        # affinity/numa stuffs
        affinitycmd=[]
        if self.pars['AFFINITY'].val!='' and self.pars['RUNMETHOD'].val != 'sge':
            if self.hasSysCmd('numactl'):
                affinitycmd=[ "numactl", "--physcpubind", self.pars['AFFINITY'].val ] #, "--localalloc" ]
            elif self.hasSysCmd('taskset'):
                affinitycmd=[ "taskset", "-c", self.pars['AFFINITY'].val ]

        # set lib path
        libpath = os.path.dirname(os.path.abspath(self.pars['EXEC_NAME'].val))
        libpath = os.path.join(libpath,"lib")
        print "adding extra libpath =",libpath
        newenv=dict(os.environ)
        #newenv['PATH'] = newenv['PATH']+':'+libpath
        if newenv.has_key('LD_LIBRARY_PATH'):
            newenv['LD_LIBRARY_PATH'] = newenv['LD_LIBRARY_PATH']+':'+libpath
        else:
            newenv['LD_LIBRARY_PATH'] = libpath

        # spawn algo
        outFileName = self.getOutFileName()
        self.outFile=open(outFileName,"w")

        nicecmd=[]
        if platform.uname()[0]!='Windows':
            if self.pars['NICE_VALUE'].val!='0':
                nicecmd = [ "nice", "-%s" %self.pars['NICE_VALUE'].val]

        print "starting \"%s\" on %s" % (self.pars['ALGORITHM'].val, self.pars['TEST_NAME'].val)
        #cmd = [ self.pars['EXEC_NAME'].val, "-nogui", "-j", "%s"%self.pars['NB_THREADS'].val]
        cmd = [ self.pars['EXEC_NAME'].val, "-nogui"]
        p = Popen(nicecmd+affinitycmd+cmd, stdout=self.outFile, stderr=self.outFile, stdin=PIPE, env=newenv)

        if ((self.pars['RUNMETHOD'].val == 'sge' or self.pars['RUNMETHOD'].val == 'slurm') and
             self.pars['LOCALDISK'].val == True and self.pars['ALGORITHM'].val != "restart" :
            # writing recovery scripts and running on local hdd
            self.cpNodeResultsScript(self.jobId)
            self.rmNodeResultsScript(self.jobId)
            p.stdin.write("setTheWDirRoot('%s')\n" %  self.getLocalDiskDir(self.jobId))

        p.stdin.write("setNumTasks(%s)\n"%self.pars['NB_TASKS'].val)
        p.stdin.write("wrap.Blas.setNumThreads(%s)\n"%self.pars['NB_THREADS'].val)
        p.stdin.write("wrap.IntelTBB.setNumThreads(%s)\n"%self.pars['NB_THREADS'].val)
        if self.pars['ALGORITHM'].val=="meta":
            p.stdin.write("load(r'%s')\n" % (self.pars['TEST_NAME'].val))
            p.stdin.write("meta()\n")
        elif self.pars['ALGORITHM'].val=="execfile":
            p.stdin.write("__file__=r'%s'\n" % (self.pars['TEST_NAME'].val)) # needed by .pythonrc.py
            p.stdin.write("execfile(r'%s')\n" % (self.pars['TEST_NAME'].val))
        elif self.pars['ALGORITHM'].val=="restart":
            p.stdin.write("load(r'%s')\n" % self.pars['TEST_NAME'].val)
            p.stdin.write("restart(%s)\n" % self.pars['RESTART_STEP'].val)
        elif self.pars['ALGORITHM'].val=="import":
            p.stdin.write("import os ; print os.environ\n")
            p.stdin.write("import %s\n" % self.pars['TEST_NAME'].val)

        p.stdin.write("quit()\n")
        p.stdin.close()
        # waiting execution time
        retcode = p.wait()
        # recovering results and removing scripts
        if (self.pars['RUNMETHOD'].val == 'sge' or self.pars['RUNMETHOD'].val == 'slurm') and
                 self.pars['LOCALDISK'].val == True and self.pars['ALGORITHM'].val != "restart":
            print "Getting back local disk workspace to home disk"
            self.moveLocalDir2Home(self.jobId)
            if os.path.isdir(self.getLocalDiskDir(self.jobId)): # si la copie a été bien faite => le local dir a été nettoyé => on peut virer les scripts
                if os.path.isfile(self.cpNodeResultsScriptName(self.jobId)):
                    os.remove(self.cpNodeResultsScriptName(self.jobId))
                if os.path.isfile(self.rmNodeResultsScriptName(self.jobId)):
                    os.remove(self.rmNodeResultsScriptName(self.jobId))
        self.outFile.close()

        # grep results + e-mail
        import StringIO
        res=StringIO.StringIO()
        res.write("cwd=%s\n" % os.getcwd())
        for file in glob.glob('%s.*.txt'%self.pars['OUTFILE'].val):
            res.write("result file : %s\n"%file)
            for line in open(file,'r'):
                for txt in ["ERROR", "Error", "error", "TSC-", "Successful", "Problem at time"]:
                    if line.find(txt)!=-1:
                        res.write(line)

        if self.pars['SEND_MAIL'].val == True:
            self.mailmsg("job %s done" % self.pars['TEST_NAME'].val, text=res.getvalue())
        res.close()
'''
if __name__ == "__main__":

    from argparse import ArgumentParser
    parser = ArgumentParser(description="Metafor's Launcher")

    # definition of arguments
    parser.add_argument('-d', '--directory', dest='rundir',
                      metavar='DIR', help='specify run directory (batch mode)')
    parser.add_argument('-x', '--nogui', action='store_false',
                      dest='usegui',default=True, help='disable menu')
    parser.add_argument('-i', '--jobId', dest='jobId', type=str, default='',
                       help='job id')

    # Parsing arguments
    args = parser.parse_args()
    #if len(args)!=0:
    #    parser.error("too many arguments")

    # starting launch
    if args.rundir:
        os.chdir(args.rundir)

    job = LaunchJob(args.jobId)

    if args.usegui:
        job.menu()
    else:
        job.run()