#!/usr/bin/python
import socket  
import threading
import time
import random
import exceptions


class CcsExecutionResult:
    def __init__(self, thread):
        self.thread = thread;

    def isRunning(self):
        return self.thread.running;

    def getOutput(self):
        while self.thread.running:
            time.sleep(0.1);
        return self.thread.executionOutput;
            

class CcsException(Exception):
    def __init__(self, value):
        self.value = value;
    def __str__(self):
        return repr(self.value);



class CcsPythonInterpreter:
    port = 4444;
    host = None;

    def __init__(self, host=None,port=4444):
        CcsPythonInterpreter.port = port;
        if host == None:
            CcsPythonInterpreter.host = socket.gethostname() # Get local machine name
        else:
            CcsPythonInterpreter.host = host;
        try:
            testSocketConnection = CcsPythonInterpreter.__establishSocketConnectionToCcsPythonInterpreter__();
            testSocketConnection.close();
            print 'Initialized connection to CCS Phython interpreter on on host ', CcsPythonInterpreter.host,':',CcsPythonInterpreter.port;
        except :
            raise CcsException("Could not establish a connection with CCS Phython Interpreter on host "+CcsPythonInterpreter.host+":"+str(CcsPythonInterpreter.port));

    @staticmethod
    def __establishSocketConnectionToCcsPythonInterpreter__():
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         s.connect((CcsPythonInterpreter.host, CcsPythonInterpreter.port))
         return s;



#    def executeScriptFromFile(self, fileName):
#        fo = open(fileName, "r");
#        content = fo.read();
#        result = self.sendInterpreterServer(content);
#        fo.close()
#        return result;

    def aSyncExecution(self, statement):
        return self.sendInterpreterServer(statement);

    def syncExecution(self, statement):
        result = self.sendInterpreterServer(statement);
        output = result.getOutput();
        return result;

    def sendInterpreterServer(self, content):
        threadId = str(int(round(time.time() * 1000)))+"-"+str(random.randint(0,1000));
        thread = _CcsPythonExecutorThread(threadId);
        thread.executePhythonContent(content);
        return CcsExecutionResult(thread);



class _CcsPythonExecutorThread:

    def __init__(self, threadId):
        self.s = CcsPythonInterpreter.__establishSocketConnectionToCcsPythonInterpreter__();
        self.threadId = threadId;
        self.outputThread = threading.Thread(target=self.listenToSocketOutput);


    def executePhythonContent(self,content):
        self.running = True;
        self.outputThread.start();        
        content = "startContent:"+self.threadId+"\n"+content+"endContent:"+self.threadId+"\n";
        self.s.send(content);
        return CcsExecutionResult(self);

    def listenToSocketOutput(self):
        self.executionOutput = "";
        while self.running:        
            output = self.s.recv(1024)
            self.executionOutput += output
            if "doneExecution:"+self.threadId in self.executionOutput:
                self.running = False;
                self.executionOutput = self.executionOutput.replace("doneExecution:"+self.threadId+"\n","");
        self.outputThread._Thread__stop();
        self.s.close();

 