#! /usr/bin/env python
##
## BUG: this script cannot correctly handle AMPL option values that contain a white space.
##

import signal
import commands
import sys
import re
import os
import random
import math
import types
pathname = os.path.dirname(sys.argv[0])
fullpath = os.path.abspath(pathname)
os.sys.path = os.sys.path + [fullpath + "/../../exact/src"]
import exact

#
# Process the output log
#
def process_log(OUTPUT,logfile):
	status = 1
	leak_flag=False
	valgrind_leaks="-1"
	valgrind_errors="-1"
	if os.path.exists(logfile):
	   INPUT = open(logfile,"r")
	   for line in INPUT:
	     #print "LINE",line
	     words = re.split('[ \t]+',line.strip())
	     if len(words) < 2:
	        continue

	     if words[0] == "Final-Value:":
	        status = 0
	        print >>OUTPUT, "Value numeric/double " + words[1]

	     elif words[0] == "Final-Point:":
	        print >>OUTPUT, "Final-Point text/string \""," ".join(words[1:]),"\""

	     elif words[0] == "Final-Stats:":
	        print >>OUTPUT, "Num-Evaluations numeric/integer " + words[2]
	        print >>OUTPUT, "ConstraintViolation numeric/double " + words[4]

	     elif words[0] == "Termination:":
	        print >>OUTPUT, "TerminationStatus text/string \"" + words[1] + "\""

	     elif words[0] == "ModelStatus:":
	        print >>OUTPUT, "ModelStatus text/string \"" + words[1] + "\""

	     elif words[0] == "SolverStatus:":
	        print >>OUTPUT, "SolverStatus text/string \"" + words[1] + "\""

	     elif words[0] == "Repetition-Check:":
	        print >>OUTPUT, "Repetition-Check text/string \"" + words[1] + "\""

	     elif words[0] == "Coliny:" and words[1] == "Solver:":
	        print >>OUTPUT, "Coliny-Solver text/string \"" + words[2] + "\""

             elif words[0] == "CPU" and words[1] == "RunTime=":
                print >>OUTPUT, "\"CPU RunTime\" numeric/double " + words[2]

             elif words[0] == "CPU" and words[1] == "TotalTime=":
                print >>OUTPUT, "\"CPU TotalTime\" numeric/double " + words[2]

             elif words[0] == "WallClock" and words[1] == "TotalTime=":
                print >>OUTPUT, "\"WallClock TotalTime\" numeric/double " + words[2]

             elif words[0] == "Seed:":
                print >>OUTPUT, "Seed numeric/integer",eval("int(" + words[1] + ")")

             #
             # When running under AMPL, the first set of valgrind statistics is the
             # one's that we want
             #
             elif words[1] == "ERROR" and words[2] == "SUMMARY:" and valgrind_errors == "-1":
                valgrind_errors = words[3]
             elif leak_flag==True and words[1] == "definitely" and valgrind_leaks == "-1":
                valgrind_leaks = words[3]
                leak_flag=False

             elif words[1] == "LEAK" and words[2] == "SUMMARY:":
                leak_flag=True

        #
        # Remove commas from valgrind #'s
        #
        p = re.compile( ',' )
        valgrind_errors = p.sub( "", valgrind_errors)
        valgrind_leaks = p.sub( "", valgrind_leaks)
        print >>OUTPUT, "\"Valgrind Errors\" numeric/integer " + valgrind_errors
        print >>OUTPUT, "\"Valgrind Leaks\" numeric/integer " + valgrind_leaks
	print >>OUTPUT, "exit_status numeric/integer " + `status`;



##
## MAIN
##
#
# Setup signal handler
#
if sys.version_info[0:2] >= (2,4):
   signal.signal(signal.SIGTERM, exact.signal_handler)
   signal.signal(signal.SIGINT, exact.signal_handler)
#
# Process factors
#
(factor,option,solvers,solver_options) = exact.process_input_file(sys.argv[2],hybrid=True)
option.set("seed",int(option["seed"]))
#
# Process the options and setup the command line
#
if "EXACT_DRIVER" in os.environ.keys():
   driver = os.environ["EXACT_DRIVER"]
else:
   driver = ""
cwd =  fullpath + "/" + os.path.dirname(sys.argv[2])
if sys.argv[1] == "--shell":
   #
   # TODO - setup shell command tests
   #
   cmd = driver + " colinytest"
   for key in option.keys():
     if key[0] != '_':
        try:
           cmd = cmd + " --" + key + "=\"" + option[key] + "\""
        except:
           cmd = cmd + " --" + key + "=" + `option[key]` + ""
   cmd = cmd + " " + option["_data"]
elif sys.argv[1] == "--ampl":
   #
   # Run AMPL
   #
   modfile = os.path.splitext(sys.argv[2])[0] + ".mod"
   cmd = driver + " ampl " + os.path.basename(modfile)
   OUTPUT = open(modfile,"w")
   words = re.split('[ \t]+',option["_data"])
   for word in words:
     if word[0] != "/":
        print >>OUTPUT, "include ../../" + word + ";"
     else:
        print >>OUTPUT, "include " + word + ";"
   if sys.platform == "cygwin":
      solverpath = commands.getoutput("cygpath -d " + fullpath)
   else:
      solverpath = fullpath
   print >>OUTPUT, "option solver \"" + solverpath + "/colinytest\";"

   print >>OUTPUT, "option coliny_options (\"",
   if option["_exact_debug"] == 1:
      print >>OUTPUT, "output_header=verbose",
   print >>OUTPUT, "seed=" + `option["seed"]`,
   for key in solver_options[solvers[0]].keys():
     if key[0] != '_':
	val = solver_options[solvers[0]][key]
        try:
           print >>OUTPUT, key + "=" + val,
        except:
           print >>OUTPUT, key + "=" + `val`,
   print >>OUTPUT, " \");"

   if len(solvers) > 1:
      for i in range(1,len(solvers)):
        print >>OUTPUT, "option " + solvers[i] + "_options (\"",
        for key in solver_options[solvers[i]].keys():
          if key[0] != '_':
	     val = solver_options[solvers[i]][key]
             try:
                print >>OUTPUT, key + "=" + val,
             except:
                print >>OUTPUT, key + "=" + `val`,
        print >>OUTPUT, " \");"
        
   print >>OUTPUT, "solve;"
   OUTPUT.close()

else:
   raise IOError, "Unknown option " + sys.argv[1]
print "Command Line: " + cmd
exact.run_command(cmd,os.path.basename(sys.argv[4]),cwd=cwd)
#
# Generate a measurements file (*.out)
#
OUTPUT = open(sys.argv[3],"w")
process_log(OUTPUT,sys.argv[4])
OUTPUT.close()
