#!/usr/bin/env python
#
# exact - process an XML file that defines an EXACT operation:
#
#	1. a computational experiment
#	2. a computational analysis
#	3. an experimental study, containing one or more experiments or
#		analyses
#

import signal
import sys
import os
import glob
import string
#
# Setup exact python path so it can find the exact python package
#
pathname = os.path.dirname(sys.argv[0])
fullpath = os.path.abspath(pathname)
os.sys.path = os.sys.path + [fullpath + "/.."] + [fullpath + "/../packages/exact/src"] + [os.getcwd()] + [fullpath + "exact/src"]
import exact


#
# Function to print help information
#
def print_help():
  print "\
exact - a python script for running an XML-defined experiment\n\
\n\
usage:\n\
\n\
   exact [options...] <exp-file> [<exp-file> ... <exp-file>]\n\
\n\
options:\n\
\n\
   --tag=<label>\tExecute an experiment only if it has a matching tag\n\
                 \telement. If no tag element is specified, then run\n\
                 \tan experiment without regard to the experiment's\n\
                 \ttag element values.\n\
\n\
   --experiment=<expr>\n\
   --analysis=<expr>\n\
          \t\tRun a specific analysis or experiment.  One or more\n\
          \t\titems can be specified, if a regular expression\n\
          \t\tis used.\n\
\n\
   --help\t\tPrint help information.\n\
\n\
   --debug\t\tAdd debugging information.\n\
\n\
   --scenario=<name>\tSpecify the scenario name.\n\
\n\
   --cleanup\t\tCleanup experimental files.\n\
\n\
   -f\n\
   --force\t\tForce the deletion of old experimental files.\n\
"


#
# Delete files generated during the execution of an analysis, 
# experiment, or experimental study.
#
# NOTE: this only looks for experimental study files right now...
#
def perform_cleanup():
  files = glob.glob("*.study.xml")
  for file in files:
    obj = exact.ExperimentalStudy(file,False)
    obj.clean()


#
# The 'main' function
#
def main():
  if (len(sys.argv) < 2):
     print_help()
     sys.exit(1)
  #
  # Get the path where this executable is located
  #
  pathname = os.path.dirname(sys.argv[0])
  fullpath = os.path.abspath(pathname)
  #os.environ["TESTLIBDIR"] = fullpath + " " + fullpath + "/../packages/exact/src"
  os.environ["PATH"] = os.environ["PATH"] + ":" + fullpath + ":" + fullpath + "/../packages/exact/src" + ":" +  fullpath + "/../packages/exact/src/exact" + ":" + fullpath + "/.." + ":" + fullpath + "/exact/src/exact" + ":" + fullpath + "/ exact/src/"
  #
  # Process the command line
  #
  experiment=None
  analysis=None
  taglist = []
  xmlfiles = []
  factors = []
  delete_old_files=False
  i=1
  while (i < len(sys.argv)):
    if sys.argv[i] == "-f":
       argv_val = "--force"
    else:
       argv_val = sys.argv[i]

    if (argv_val).startswith("--") == False:
       xmlfiles = xmlfiles + [argv_val]
       i = i + 1
       break
    else:
       tmp = (argv_val.replace("--","")).split("=")
       #
       # Process options
       #
       if tmp[0] == "help":
	  print_help()
	  sys.exit(1)

       if tmp[0] == "debug":
	  exact.global_data.debug=True

       if tmp[0] == "force":
	  delete_old_files=True

       if tmp[0] == "cleanup":
	  perform_cleanup()

       if tmp[0] == "experiment":
	  experiment=tmp[1]

       if tmp[0] == "analysis":
	  analysis=tmp[1]

       if tmp[0] == "tag":
	  taglist = taglist + [tmp[1]]

       #if tmp[0] == "scenario":
          #os.putenv("RUNEXP_SCENARIO",tmp[1])

    i = i + 1
  if (i<len(sys.argv)):
     if exact.isint(sys.argv[i]):
        while (i < len(sys.argv)):
          factors =  factors + [ eval(sys.argv[i]) ]
          i = i + 1
     else:
        while (i < len(sys.argv)):
          if exact.isint(sys.argv[i]):
             print "ERROR: It looks like factors have been specified after two or"
             print "ERROR: more experiments have been given"
             sys.exit(1)
          xmlfiles = xmlfiles + [sys.argv[i]]
          i = i + 1
  if analysis==None and experiment==None:
     analysis='.*'
     experiment='.*'
  else:
     delete_old_files=True
  load_results= (experiment==None)
  #
  # Process the XML files
  #
  for xmlfile in xmlfiles:
    if xmlfile == "unknown":
       print "ERROR: an experiment file has not been specified."
       sys.exit(1)
    if exact.global_data.debug and len(factors) > 0:
       print "Factors: " + factors
    #
    # Read experimental study file
    #
    # Note: this has the auto-loading of results disabled
    #
    if exact.global_data.debug==True:
       print "      Reading file: " + xmlfile
    exact_obj = exact.GenericInterface(xmlfile,load_results=load_results)
    #
    # Execute this study if it has the right tags
    #
    if isinstance(exact_obj,exact.ExperimentalStudy):
       exact_obj.execute(taglist,factors,force=delete_old_files,analysis_name=analysis,experiment_name=experiment)
    #
    # Execute this experiment
    #
    elif isinstance(exact_obj,exact.Experiment):
       exact_obj.execute(factors)
    #
    # Execute this analysis
    #
    elif isinstance(exact_obj,exact.AnalysisBase):
       exact_obj.execute()
    else:
       print "ERROR: unknown exact object type!"
       sys.exit(1)
    
##
## Launch 'main' if in interactive mode
##
if __name__ == '__main__':
    signal.signal(signal.SIGTERM, exact.signal_handler)
    signal.signal(signal.SIGINT, exact.signal_handler)
    main()
