import os
import library2
import time

class ABSServer:
    
    def __init__(self,ipSource="localhost", ipDestino="192.168.1.117", portDestino=7000, ipDestino2="192.168.1.11", portDestino2=5500):
    
        self.ipSource = ipSource
        self.ipDestino = ipDestino
        self.portDestino = portDestino
        
        self.ipDestino2 = ipDestino2
        self.portDestino2 = portDestino2
        
        self.tx_buffer = "default"
        self.rx_buffer = "default"
        
        self.createObjects()
        
    def createObjects(self):
        
        asServer = True
        self.commServerObj = library2.TCPComm("Central_Control", self.ipDestino, self.portDestino, asServer)
        self.commClientObj = library2.TCPComm("Central_Control", self.ipDestino2, self.portDestino2)
            
    def waitRequest(self):
        
#        Using rx buffer
        ipSource, ipDestino, cmd, self.rx_buffer = self.commServerObj.waitServer()
        
        if cmd == "SNDF":
            datarpta = self.sendFile2Modules(mode=2, cmd = cmd)
        
        if cmd == "CHGB":
            datarpta = self.changeBeam(cmd = cmd)
        
        if cmd == "ANST":
            self.getStatus(mode=4, cmd = cmd)
#        Using tx buffer
            datarpta = self.tx_buffer
        
        self.commServerObj.sendData2(cmd=cmd, data=datarpta, ipDestino = ipSource)

    def checkModule(self, address):
        
        cmd = "ping -c 1 -w 1 192.168.1."+ str(address) + " >> /dev/null"
        status = os.system(cmd)
        
        if status == 256:
            return False
        
        return True

    def __writeReport(self, enaModules):
        
        status_array = ["Status of modules\n"]
        status_array.append("----------------\n")
        
        for address in range(1,65):
            if address in enaModules:
                status_array.append("192.168.1." + str(address) + " [1 1]\n")
            else:    
                status_array.append("192.168.1." + str(address) + " [0 0]\n")
        
        f = open("module_status.txt","w")
        f.writelines(status_array)
        f.close()
    
    def checkAntenna(self):
        
        """
        Direccion de los modulos de las antenas:
        
            Norte    :    01-16
            Este     :    17-32
            Oeste:   :    33-48
            Sur      :    49-64
        
        """
        
        enaModules = []
        
        for address in range(1,65): 
            if self.checkModule(address):
                enaModules.append(address)
        
        self.__writeReport(enaModules)
        return  enaModules

    def sendFile2Modules(self, mode, cmd):
        
        if mode == 1:
            self.__sendFile2Modules1()           
        else:
            self.__sendFile2Modules2(cmd)
             
    def __sendFile2Modules1(self):

        #Needed for the loop
        rx_frame_list = self.rx_buffer.split('\n',2)
        
        self.experiment_name = rx_frame_list[0]
        experiment_number = rx_frame_list[1]
        str_control_modules = rx_frame_list[2]
        
        lst_control_modules = str_control_modules.split("------\n")
        
#        enaModules = self.checkAntenna()
        enaModules = [11,12,13,14]
        
        for address in range(1,65):
            
            if address not in enaModules:
                continue
            
            self.__writeModuleFile(self.experiment_name, lst_control_modules[address-1])
            
            cmd = "tftp -m binary 192.168.1."+ str(address) +" 69 -c put " + self.experiment_name
            print cmd
            os.system(cmd)
        
        self.__loadFile()

    def __sendFile2Modules2(self,cmd):

        #Needed for the loop
        rx_frame_list = self.rx_buffer.split('\n',2)
        correct = 0
        failure = 0
        header = rx_frame_list[0] + "\n"
        str_control_modules = rx_frame_list[2]
        
        lst_control_modules = str_control_modules.split("------\n")
        
#        enaModules = self.checkAntenna()
        enaModules = [11,12,13,14]
        
        for id in range(1,65):
            
            if id not in enaModules:
                continue
            #tcp client needed
            self.commClientObj.open_socket()
            ip = "192.168.1." + str(id)
            self.commClientObj.sendData2(cmd, header + lst_control_modules[id-1], ip)
            ipSource, ipDestino, cmd, tmp = self.commClientObj.waitClient()
            self.commClientObj.close_socket()
            
            if tmp == "OK":
                correct = correct + 1
            else:
                failure = failure + 1
                
        if correct == len(enaModules):
            rpta = "OK"
        else:
            rpta = "Failure"

        return rpta
        

    def __writeModuleFile(self, filename, str):
        
        fobj = open(filename,"w")
        fobj.write(filename + "\n")
        fobj.write("------\n")
        fobj.write(str)
        fobj.write("------\n")
        fobj.close()

    def __readModuleFile(self, filename):
        
        fobj1 = open(filename,"r")
        file_list_1 = fobj1.readlines()
        fobj1.close()
        content_str = ''.join(file_list_1[2:-1])
            
        return content_str 
    
    def __loadFile(self):
        
        #Working with the UDP socket
        self.commClientObj.sendData("none", "CARGA:" + self.experiment_name + ":")
        self.commClientObj.sendData("none", "CAMBIA:0:")
            
    def changeBeam(self, cmd):
        
        correct = 0
        failure = 0
#        enaModules = self.checkAntenna()
        enaModules = [11,12,13,14]
        
        for id in range(1,65):
            if id not in enaModules:
                continue
            
            self.commClientObj.open_socket()
            ip = "192.168.1." + str(id)
            self.commClientObj.sendData2(cmd, self.rx_buffer, ip)
#            ipSource, ipDestino, cmd, tmp = self.commClientObj.waitData()
            ipSource, ipDestino, cmd, tmp = self.commClientObj.waitClient()
            self.commClientObj.close_socket()
        
            if tmp == "OK":
                correct = correct + 1
            else:
                failure = failure + 1
                
        if correct == len(enaModules):
            rpta = "OK"
        else:
            rpta = "Failure"

        return rpta
     
    def getStatus(self, mode, cmd):
        
        if mode == 1:
            self.__getStsMode1()
        elif mode == 2:
            self.__getStsMode2()
        elif mode == 3:
            self.__getStsMode3()            
        else:
             self.__getStsMode4(cmd)
                     
    
    def __getStsMode1(self):
        #rpta = self.commClientObj.sendTxRxCommand(cmd='CHEQUEO', data="0")
        self.commClientObj.sendData("CHEQUEO:" + self.rx_buffer + ":")
        seconds = int (self.rx_buffer)
        # Give 5 seconds to the control modules        
        time.sleep(seconds)
        # Checking the module connection
        module_list = self.connection_status(10)
        #Generating the complete report
        module = 1
        number_of_modules = 16 
        filename1 = "Verificacion"
        filename2 = "report.txt"  
        fobj2 = open(filename2,"w")
        fobj2.write("Verification_file\n")
        fobj2.write("-----------------\n")
        fobj2.close()
        while module <= number_of_modules:
            if module_list[module -1] == "1":
                #Preparing and doing the tftp command
                cmd = "tftp -m binary 192.168.1."+ str(base + module) +" 69 -c get " + filename1
                print   cmd
                os.system(cmd)
                # Getting data from the control module file
                fobj1 = open(filename1,"r")
                file_list_1 = fobj1.readlines()
                fobj1.close()
                content = file_list_1[2:-1]
                # 
                fobj2 = open(filename2,"a")
                if base == 10:
                    fobj2.write("S" + str(module) + "\n")
                else:
                    fobj2.write("N" + str(module) + "\n")
                fobj2.writelines(content)
                fobj2.write("------\n")
                fobj2.close()
            module = module + 1
    
    def __getStsMode2(self):
        
        #rpta = self.commClientObj.sendTxRxCommand(cmd='CHEQUEO', data="0")
        self.commClientObj.sendData("CHEQUEO:" + self.rx_buffer + ":")
        seconds = int (self.rx_buffer)
        # Give 5 seconds to the control modules        
        time.sleep(seconds)
        # Checking the module connection
        enaModules = self.checkAntenna()
        #Generating the complete report
        filename1 = "Verificacion"
        line1 = "Verification_file\n"
        line2 = "-----------------\n"
        report_list = [line1, line2]
        
        for address in range(1,65):
            
            if address not in enaModules:
                continue
            #Preparing and doing the tftp command
            cmd = "tftp -m binary 192.168.1."+ str(address) +" 69 -c get " + filename1
            print cmd
            os.system(cmd)
            #Sub_header
            report_list.append("ABS_" + str(address) + "\n")
            # Content
            fobj1 = open(filename1,"r")
            file_list_1 = fobj1.readlines()
            fobj1.close()
            content = ''.join(file_list_1[2:-1])
            report_list.append(content)
            #Ending
            report_list.append("------\n")
        #print "\nFinalizado"
        self.tx_buffer = ''.join(report_list)
           
    def __AddingHeader(self,content_list, title):
        
        line1 = title + "\n"
        line2 = "-----------------\n"
        header_list = [line1, line2]
        verification_list = header_list + content_list
        # Arming the frame
        self.tx_buffer = ''.join(verification_list)     

    def __getModuleFile(self, filename):    
        
        enaModules = self.checkAntenna()
        content_list = []
        for address in range(1,65):
            
            if address not in enaModules:
                continue
            #Preparing and doing the tftp command
            cmd = "tftp -m binary 192.168.1."+ str(address) +" 69 -c get " + filename
            print cmd
            os.system(cmd)
            #Sub_header
            content_list.append("ABS_" + str(address) + "\n")
            # From module file to list
            content_str = self.__readModuleFile(filename)            
            content_list.append(content_str)
            content_list.append("------\n")
            
        self.__AddingHeader(content_list, title = "Verification_file")

    def __getStsMode3(self):
        
        self.commClientObj.sendData("none", "CHEQUEO:" + self.rx_buffer + ":")
        seconds = int (self.rx_buffer)
        # Give 5 seconds to the control modules        
        time.sleep(seconds)
        
        self.__getModuleFile(filename = "Verificacion")
    
    def __getStsMode4(self, cmd):

        content_str = ""
#        enaModules = self.checkAntenna()
        enaModules = [11,12,13,14]
        
        for id in range(1,65):
            if id not in enaModules:
                continue
            
            self.commClientObj.open_socket()
            ip = "192.168.1." + str(id)
            self.commClientObj.sendData2(cmd, self.rx_buffer, ip)
            ipSource, ipDestino, cmd, tmp = self.commClientObj.waitClient()
            self.commClientObj.close_socket()
        
            content_str = content_str + tmp
#        self.__AddingHeader(content_list, title = "Verification_file")
#Using tx buffer
        self.tx_buffer = content_str                          

if __name__ == '__main__': 
    
    absObj = ABSServer()
    
    while 1:
        absObj.waitRequest()