#import tftpy
import socket
        
class UDPComm:
    
    __HEADER = "ABS"
    
    def __init__(self, ipSource, ipDestino, portDestino, asServer=False):
        
        self.ipSource = ipSource
        self.ipDestino = ipDestino
        self.portDestino = portDestino
        self.addr = (ipDestino,portDestino)
        self.answer = "none"     #test
        self.mode = "none"

        
        self.openSocket(asServer)
    
    def openSocket(self, asServer):
        
        #self.socket_c = socket.socket(AF_INET,SOCK_DGRAM)
        self.socket_c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,0)
#        self.socket_c.connect((self.ipDestino, self.portDestino))
        
        if asServer:
            self.configAsServer()
            self.mode = "server"
        else:
            self.configAsClient()
            self.mode = "client"
    
    def configAsClient(self):
        #Configurar broadcast
        self.socket_c.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        
    def configAsServer(self):
        
        self.socket_c.bind(self.addr)
        print "\nServer initialized"
        
    def waitData(self, nbytes = 16384):
        
        print "\nWaiting some data"
        trama_rx, self.answer = self.socket_c.recvfrom(nbytes)
        print "\nThis socket has received some data from:"
        print self.answer
        ipSource, ipDestino, cmd, data = self.__getTrama(trama_rx)
        
        return ipSource, ipDestino, cmd, data
            
    def sendData(self, cmd, data):
        
        if self.portDestino == 7000:
            trama_tx = self.__HEADER + ":" + str(self.ipSource) + ":" + str(self.ipDestino) + ":" + str(cmd) + ":" + str(data) + ":"
        else:
            trama_tx = data
        
        if self.mode == "client":
            destiny = self.addr
        else:
            destiny = self.answer
        # Send messages
        if(self.socket_c.sendto(trama_tx, destiny)):
            print "Sending message:[" + trama_tx + "] to " + str(destiny)
    
    def __getTrama(self, trama):
        
        FrameList = trama.split(':')

        header = FrameList[0]
        ipSource = FrameList[1]
        ipDestino = FrameList[2]
        cmd = FrameList[3]
        data = FrameList[4]
        trash = FrameList[5]
        
        return ipSource, ipDestino, cmd, data

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.mode = "none"
        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.mode = "server"
        else:
#            self.configAsClient()
            self.mode = "client"        #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.mode == "client":
            # 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 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.mode == "client":
            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 __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()

#class FTPComm:
#    
#    ftp_servidor = 'ftp.servidor.com'
#    ftp_usuario  = 'miusuario'
#    ftp_clave    = 'miclave'
#    ftp_raiz     = '/public_html'
#
#    def __init__(self):
#        
#        self.client = tftpy.TftpClient(self.ftp_servidor, '69')
#        
#    
#    def sendFile(self, filename):
#        
#        self.client.upload(filename)
#        
#if __name__ == '__main__':
#    
#    obj = FTPComm()
    
        
    