'''
Created on 4 Jun 2015

@author: pedroribeiro
'''
import os
import time
import subprocess
import shutil
import threading
import Conf
from signal import SIGKILL
# from sys import stderr

class Command(object):
    def __init__(self, cmd, log, cwd=None):
        self.cmd = cmd
        self.log = log
        self.cwd = cwd
        self.process = None

    def run(self, timeout = Conf.TIMEOUT):
        def tgt():
	    print "Command" + str(self.cmd)
            self.process = subprocess.Popen(self.cmd,cwd=self.cwd,stdout=self.log,stderr=subprocess.STDOUT, preexec_fn=os.setsid)
            self.process.communicate()

        thread = threading.Thread(target=tgt)
        thread.start()

        thread.join(timeout)
        if thread.is_alive():
            print 'Terminating process'
            try:
                os.killpg(os.getpgid(self.process.pid), SIGKILL)
            except OSError:
                print "============== OSError killing a process"
            thread.join()
            self.log.write("TIMEOUT\n")
            return -1
        return self.process.returncode
        

def TOOL_COMMAND(script,log_file):
    #print "Executing "+script+" \n"
    with open(log_file,"w") as f:
        ret = Command([Conf.TOOL_HOME+"/refines", "-b", "-q", "-f", "plain", script],f).run()
        f.close()
    return ret

#./dfinder -c dfinder.config -f ~/Dropbox/PhD/Thesis/Examples/test_bip2.bip --method=fp
def DFINDER_PM_COMMAND(script,log_file):
    #print "Executing "+script+" \n"
    with open(log_file,"w") as f:
        ret = Command(["./dfinder", "-c","dfinder.config", "-f", script,"--method=pm"],f, cwd=Conf.DFINDER_HOME).run()
        f.close()
    return ret

def DFINDER_FP_COMMAND(script,log_file):
    #print "Executing "+script+" \n"
    with open(log_file,"w") as f:
        ret = Command(["./dfinder", "-c","dfinder.config", "-f", script,"--method=fp"],f, cwd=Conf.DFINDER_HOME).run()
        f.close()
    return ret

def DFINDER_LINEAR_COMMAND(script,log_file):
    #print "Executing "+script+" \n"
    with open(log_file,"w") as f:
        ret = Command(["./dfinder", "-c","dfinder.config", "-f", script,"--method=linear"],f, cwd=Conf.DFINDER_HOME).run()
        f.close()
    return ret

# def PAIR_COMMAND(script,log_file):
#     #print "Executing "+script+" \n"
#     with open(log_file,"w") as f:
#         ret = Command([Conf.TOOL_HOME+"/refines", "-b", "-q", "-f", "plain", script],f).run()
#         f.close()
#     return ret
    

def FDR3_COMMAND(script,log_file):
    #print "Executing "+script+" \n"
    with open(log_file,"w") as f:
        ret = Command([Conf.FDR3_HOME+"/refines", "-b", "-q", "-f", "plain", script], f).run()
        f.close()
    return ret

def FSDD_COMMAND(script,log_file):
    return DC_COMMAND(script,log_file, "FSDD")

def SDD_COMMAND(script,log_file):
    return DC_COMMAND(script,log_file, "SDD")
    
def CSDD_COMMAND(script,log_file):
    return DC_COMMAND(script,log_file, "CSDD")
    
def DC_COMMAND(script,log_file, method="ALL"):
    #print "Executing "+script+" \n"
    os.environ['FDRHOME'] = Conf.FDR2_HOME
    FNULL = open(os.devnull, 'w')
    #COMPRESSION_FILE_PATH = os.path.join(os.path.dirname(script),"compression.csp")
    #shutil.copy("Templates/compression.csp", COMPRESSION_FILE_PATH)
    with open("go.tcl","w") as f: 
        f.write("source compile.tcl; compile "+script+" SYSTEM Net.net")
        f.close()
    
    with open(log_file,"w") as log:
        if Command([Conf.FDR2_HOME+"/bin/fdr2tix", "-insecure", "-nowindow", "go.tcl"], FNULL).run() == -1:
            FNULL.close()
            log.write("TIMEOUT\n")
            os.remove("go.tcl")
            log.close()
            return False
        FNULL.close()
        
        ret = Command(["java", "-cp", Conf.DEADLOCK_CHECKER_HOME, "Deadlock.CommandLine", method, "Net.net"],log).run()
                
        if(ret == 0):
            log.write("true \n")
        else:
            log.write("false \n")
        log.close()
    os.remove("go.tcl")
    os.remove("Net.net")
    return ret

    
    
