class FileTransferClient(FileTransferContext):
    def __init__(self, ip, port, filePath):
        super(FileTransferClient, self).__init__()
        self.messageQueue = Queue.Queue()
        self.tcpClient = TcpClient(0, ip, port, self.messageQueue)
        self.transferType = FileTransferContext.TRANSFER_TYPE_SEND
        self.filePath = filePath
        self.fileBaseName = os.path.basename(self.filePath)
        self.fileChunkSize = COMMON.PACKET_BODY_SIZE
        pass

    def start(self):
        if not self.initTransferInfo():
            return False
        isOK = self.tcpClient.start()
        if isOK:
            self.sendFileUploadReq()
            return True
        else:
            print "fileClient start filed:", self.filePath
            return False

    def stop(self):
        self.tcpClient.disconnect()
        self.finiTransInfo()

    def isRunOk(self):
        return self.tcpClient.isConnected()

    # >>REQ
    def sendFileUploadReq(self):
        req = FILE_TRANSFER_PACKET()
        req.muCmd = FILE_CMD.CMD_FILE_UPLOAD_REQ
        req.mu32BitField = CONFIG.max_body_size
        body = dict()
        body["fileName"] = self.fileBaseName
        body["fileSize"] = self.fileTotalSize
        body_str = json.dumps(body)
        req.body = body_str
        req.muSize = req.getSize()
        self.tcpClient.sendPacket(req)
        print ">>will upload {0}".format(body_str)

    # <<RSP
    def onFileUploadRsp(self, rsp):
        # rsp = FILE_TRANSFER_PACKET()
        if rsp.muMsgId == 0:
            print "<<onFileUploadRsp ,rsp failed: cmd:{0} size:{1}".format(rsp.muCmd, rsp.muSize)
            return
        self.transferMsgId = rsp.muMsgId
        self.transferSeqNum = 1
        self.transferedSize = 0
        self.sendFileSegmentUploadReq()

    # >>REQ
    def sendFileSegmentUploadReq(self):
        buffer = self.readBuffer()
        if len(buffer) == 0:
            return
        req = FILE_TRANSFER_PACKET()
        req.muCmd = FILE_CMD.CMD_FILE_SEGMENT_UPLOAD_REQ
        req.muMsgId = self.transferMsgId
        req.mu32BitField = len(buffer)
        req.muSeqnum = self.transferSeqNum
        req.body = buffer
        req.muSize = req.getSize()
        self.tcpClient.sendPacket(req)

    # <<RSP
    def onFileSegmentUploadRsp(self, rsp):
        if rsp.muMsgId != self.transferMsgId:
            print "uploadrsp error msgid_no_math cli-msgid:{0} svr-msgid:{1}".format(self.transferMsgId, rsp.muMsgId)
            return
        if rsp.muSeqnum != self.transferSeqNum:
            print "uploadrsp error seqN_no_math cli_seq:{0} svr_seq:{1}".format(self.transferSeqNum, rsp.muSeqnum)
            return
        self.transferedSize += rsp.mu32BitField
        self.transferSeqNum += 1
        self.traceTransferInfo()
        self.sendFileSegmentUploadReq()

    def serve_once(self):
        try:
            self.tcpClient.serve_once()
            next_msg = self.messageQueue.get_nowait()
            self.OnProcessPacket(next_msg)
        except Queue.Empty:
            # print 'queue empty'
            pass
        pass

    def OnProcessPacket(self, packet_data):
        rsp = FILE_TRANSFER_PACKET()
        rsp.unpack(packet_data)
        if rsp.muCmd == FILE_CMD.CMD_FILE_UPLOAD_RSP:
            self.onFileUploadRsp(rsp)
            return
        if rsp.muCmd == FILE_CMD.CMD_FILE_SEGMENT_UPLOAD_RSP:
            self.onFileSegmentUploadRsp(rsp)
class FileTransferClient(FileTransferContext):
    def __init__(self,ip,port,filePath):
        super(FileTransferClient, self).__init__()
        self.messageQueue=Queue.Queue()
        self.tcpClient = TcpClient(0, ip,port, self.messageQueue)
        self.transferType = FileTransferContext.TRANSFER_TYPE_RECV
        self.filePath = filePath
        self.fileBaseName = os.path.basename(self.filePath)
        self.fileChunkSize = COMMON.PACKET_BODY_SIZE
        self.tmpdir=CONFIG.client_tmpdir
        pass

    def start(self):
        mkdir(self.tmpdir)
        isOK = self.tcpClient.start()
        if isOK :
            self.sendFileDownloadReq()
            return True
        else:
            print "fileClient start filed:",self.filePath
            return False

    def stop(self):
        self.tcpClient.disconnect()
        self.finiTransInfo()

    def isRunOk(self):
         return self.tcpClient.isConnected()


   #>>REQ
    def sendFileDownloadReq(self):
        req = FILE_TRANSFER_PACKET()
        req.muCmd = FILE_CMD.CMD_FILE_DOWNLOAD_REQ
        req.mu32BitField = CONFIG.max_body_size
        body = dict()
        body["fileName"] = self.filePath
        body_str = json.dumps(body)
        req.body = body_str
        req.muSize = req.getSize()
        self.tcpClient.sendPacket(req)
        print ">>will download {0}".format(body_str)

    #<<RSP
    def onFileDownloadRsp(self,rsp):
        #rsp = FILE_TRANSFER_PACKET()
        if rsp.muMsgId == 0:
            print "<<onFileDownloadRsp ,rsp failed: cmd:{0} size:{1}".format(rsp.muCmd,rsp.muSize)
            return
        self.transferMsgId=rsp.muMsgId
        self.fileTotalSize=rsp.mu32BitField
        if self.fileTotalSize == 0:
            print "cannot find file:{0} from server".format(self.filePath)
            return
        self.fileBaseName=os.path.basename(self.filePath)
        self.initTransferInfo()
        self.transferSeqNum=0
        self.transferedSize=0
        self.sendFileDownReceipt()

    # >>REQ
    def sendFileDownReceipt(self):
        req = FILE_TRANSFER_PACKET()
        req.muCmd = FILE_CMD.CMD_FILE_SEGMENT_DOWNLOAD_RECIPT
        req.muSeqnum=self.transferSeqNum
        req.muMsgId = self.transferMsgId
        req.muSize = req.getSize()
        self.tcpClient.sendPacket(req)

    # <<RSP
    def onFileSegmentDownloadRsp(self,rsp):
        if rsp.muMsgId != self.transferMsgId:
            print "uploadrsp error msgid_no_math cli-msgid:{0} svr-msgid:{1}".format(self.transferMsgId,rsp.muMsgId)
            return
        self.writeBuffer(rsp.body)
        self.transferSeqNum = rsp.muSeqnum
        self.traceTransferInfo()
        if self.isFinished():
            print "finished"
            pass
        else:
            self.sendFileDownReceipt()

    def serve_once(self):
        try:
            self.tcpClient.serve_once()
            next_msg = self.messageQueue.get_nowait()
            self.OnProcessPacket(next_msg)
        except Queue.Empty:
            #print 'queue empty'
            pass
        pass

    def OnProcessPacket(self,packet_data):
        rsp = FILE_TRANSFER_PACKET()
        rsp.unpack(packet_data)
        if rsp.muCmd == FILE_CMD.CMD_FILE_DOWNLOAD_RSP:
            self.onFileDownloadRsp(rsp)
            return
        if rsp.muCmd == FILE_CMD.CMD_FILE_SEGMENT_DOWNLOAD_NOTIFY:
            self.onFileSegmentDownloadRsp(rsp)