import threading, Queue
import whatap.agent.conf.configure as config
import whatap.agent.secure.security_master as secure
from whatap.io.data_outputx import DataOutputX
import whatap.net as net
from whatap.pack.pack import Pack as pack
from whatap.util.date_util import DateUtil as dateutil
import whatap.util.logging_util as logging_util
import whatap.net.tcpsession as tcpsession
import time

class TcpSend:
    def __init__(self, f, p):
        self.__flag = f
        self.__pack = p

    @property
    def flag(self):
        return self.__flag

    @property
    def pack(self):
        return self.__pack

def Send(f , p):
    __sender.queue(TcpSend(f, p))

class __Sender(threading.Thread):
    def __init__(self) :
        threading.Thread.__init__(self, name='__Sender')
        self.setDaemon(True)
        self.__queue = Queue.Queue()

    def queue(self, sendinfo):
        self.__queue.put(sendinfo)

    def run(self):
        conf = config.GetConfig()
        cypher_level = conf.CypherLevel

        last_time_sync = int(0)
        while True:
            try:
                conf = config.GetConfig()
                p = self.__queue.get()
                secuTcp = secure.GetSecuritySession()
                session = tcpsession.GetTcpSession()

                if not session.isOpen():
                    time.sleep(0.001)
                    continue
                if cypher_level != conf.CypherLevel:
                    cypher_level = conf.CypherLevel
                    session.Close()
                    time.sleep(0.001)
                    continue
                now = dateutil.now()

                if now > last_time_sync+conf.TimeSyncInterval * 1000:
                    last_time_sync = now
                    session.Send(net.NET_TIME_SYNC, DataOutputX.toBytesLong(now))

                if conf.CypherLevel == 0:
                    b = pack.toBytesPack(p.pack)
                    session.Send(p.flag, b)
                else:
                    secureMask = net.GetSecureMask(p.flag)

                    if secureMask == net.NET_SECURE_HIDE:
                        if secuTcp.cypher is not None:
                            b = pack.toBytesPack(p.pack)
                            b = secuTcp.cypher.HideLong(b)
                            session.Send(p.flag, b)
                    elif secureMask == net.NET_SECURE_CYPHER:
                        if secuTcp.cypher is not None:
                            b = pack.toBytesPackECB(p.pack, int(conf.CypherLevel/8))
                            b = secuTcp.cypher.Encrypt(b)
                            session.Send(p.flag, b)
                    else:
                        b = pack.toBytesPack(p.pack)
                        session.Send(p.flag, b)
            except Exception, e:
                logging_util.logStack(e)
                time.sleep(0.001)
__sender = __Sender()
__sender.start()
