import socket

class TCPComm:
    
    __HEADER = "JRO"
    __TYPE = "ABS"
    
    def __init__(self, ipSource, ipDestino, portDestino, asServer=False):
        
        self.ipSource = ipSource
        self.ipDestino = ipDestino
        self.portDestino = portDestino
        self.addr = (ipDestino,portDestino)
        
        self.sc = "none"
        self.answer = "none"     #test
        self.asServer = False
        self.len = 0
        self.crc = 0
        
        self.openSocket(asServer)
    
    def openSocket(self, asServer):
        
        #self.socket_c = socket.socket(AF_INET,SOCK_DGRAM)
#        self.socket_c = socket.socket()
#        self.socket_c.connect((self.ipDestino, self.portDestino))
        
        if asServer:
            self.socket_c = socket.socket()
#            self.configAsServer()
            self.socket_c.bind(self.addr)
            self.asServer = True
        else:
#            self.configAsClient()
            self.asServer = False        #Socket is opened at the sendData function
    
#    def configAsClient(self):
        #Buscar broadcast TCP
#        self.socket_c.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
#         self.socket_c.connect(self.addr)
#         pass
        
#    def configAsServer(self):
#        
#        self.socket_c.bind(self.addr)
        
    def waitData(self, nbytes = 1024):
        
        print "\nWaiting some client."
        
        if self.asServer == False:
            # Short data through ethernet
            trama_rx = self.socket_c.recv(nbytes)
        else:
            self.socket_c.listen(1)
            sc, addr = self.socket_c.accept()
            self.sc = sc
            self.answer = addr
            # Big data through ethernet
            trama_rx = ""
            while True:
                tmp = self.sc.recv(nbytes)
                trama_rx = trama_rx + tmp
                if trama_rx[-4:] == "quit":
                    break 

        print "\nThis socket has received some data."

        ipSource, ipDestino, cmd, data = self.__getTrama(trama_rx)
        
        return ipSource, ipDestino, cmd, data
            
    def waitServer(self, nbytes = 1024):
        
        print "\nWaiting some client."
        self.socket_c.listen(1)
        sc, addr = self.socket_c.accept()
        self.sc = sc
        self.answer = addr
        # Big data through ethernet
        trama_rx = ""
        while True:
            tmp = self.sc.recv(nbytes)
            trama_rx = trama_rx + tmp
            if trama_rx[-4:] == "quit":
                break 

        print "\nThis socket has received some data from: " + str(self.answer)

        ipSource, ipDestino, cmd, data = self.__getTrama(trama_rx)
        
        return ipSource, ipDestino, cmd, data
    
    def waitClient(self, nbytes = 1024):
        
        print "\nWaiting the server."    
            # Short data through ethernet
        trama_rx = self.socket_c.recv(nbytes)
        
        print "\nThis socket has received this data: " + str(trama_rx)
        
        ipSource, ipDestino, cmd, data = self.__getTrama(trama_rx)
        
        return ipSource, ipDestino, cmd, data
        
    def sendData(self, cmd, data, id):
        
        trama_tx = self.__HEADER + ":" + self.__TYPE + ":" + str(self.ipSource) + ":" + str(self.ipDestino) + \
        ":" + str(self.len) + ":" + str(cmd) + ":" + str(data) + ":" + str(self.crc)

        if self.portDestino == 7000:
            trama_tx = trama_tx  + ":" + "quit" 
        # Send messages
        if self.asServer == False:
            host = "192.168.1." + str(id)
            self.socket_c.connect((host, self.portDestino))
            self.socket_c.send(trama_tx)
        else:
            self.sc.send(trama_tx)
        print "Sending message:[" + trama_tx + "]"

    def sendData2(self, cmd, data, ipDestino):

        trama_tx = self.__HEADER + ":" + self.__TYPE + ":" + str(self.ipSource) + ":" + str(ipDestino) + \
        ":" + str(self.len) + ":" + str(cmd) + ":" + str(data) + ":" + str(self.crc) + ":" + "quit"
        
        if self.asServer == True:
            self.SendAsServer(trama_tx)
        else:
            self.SendAsClient(ipDestino, trama_tx)
        
    def SendAsServer(self, trama_tx):
        
        self.sc.send(trama_tx)
        print "Sending message:[" + trama_tx + "] to: " + str(self.answer)        
        
    
    def SendAsClient(self, ipDestino, trama_tx):

        self.socket_c.connect((ipDestino, self.portDestino))
        self.socket_c.send(trama_tx)
        print "Sending message:[" + trama_tx + "] to: " + ipDestino
    
    def __getTrama(self, trama):
        
        FrameList = trama.split(':')

        header = FrameList[0]
        TypeOfInstrument = FrameList[1]
        ipSource = FrameList[2]
        ipDestino = FrameList[3]
        len = FrameList[4]
        cmd = FrameList[5]
        data = FrameList[6]
        crc = FrameList[7]
        trash = FrameList[8]
        
        return ipSource, ipDestino, cmd, data

    def close_socket(self):
        self.socket_c.close()

    def open_socket(self):
        self.socket_c = socket.socket()