import platform, threading, Queue, time
import whatap.util.logging_util as logging
import whatap.agent.conf.configure as config
import whatap.io as io
import whatap.lang.license as license
from whatap.util.ip_util import IPUtil
import whatap.util.cypher as cypher
from whatap.io.data_inputx import DataInputX
from whatap.util.hash_util import HashUtil


class __SecurityMaster(threading.Thread):
    def __init__(self) :
        threading.Thread.__init__(self, name='__Sender')
        self.setDaemon(True)
        self.__queue = Queue.Queue()
        self.pcode = 0
        self.oid = 0
        self.ip = None
        self.oname = None
        self.secureKey = None
        self.cypher = None
        self.lastOidSent = None
        self.publicip = None

    def run(self):
        conf = config.GetConfig()
        oldLic = ""
        while True:
            if conf.License and conf.License != oldLic :
                oldLic = conf.License
                self.resetLicense(conf.License)

            time.sleep(3)

    def DecideAgentOnameOid(self, myIp ):
        self.ip = DataInputX.toInt(IPUtil.toBytes(myIp), 0)
        self.oname = config.GetConfig().oname
        if self.oname == '':
            self.oname = platform.uname()[1]
        oidOverride = config.GetConfig().oid
        ipreg = config.GetConfig().ipreg

        if oidOverride:
            self.oid = int(oidOverride)
        else:
            self.oid = HashUtil.hashFromString("WHATAP_SM%s%s"%(config.GetConfig().CreatedTime, myIp))
            if not ipreg:
                kv = {"oid":self.oid}
                config.SetValues(kv)

        infoMessage = "oid = {}, oname = {}, creatdtime = {}, ip = {}".format(self.oid, self.oname, config.GetConfig().CreatedTime, myIp)
        logging.info(infoMessage)

    def resetLicense(self, lic ):
        if not lic:
            logging.error("license read fail")
            return
        #print("resetLicense", lic)
        pcode, security_key = license.Parse(lic)
        self.pcode = pcode
        self.secureKey = security_key
        self.cypher = cypher.NewCypher(self.secureKey, 0)


    def WaitForInit(self) :
        while self.cypher is None or self.oname is None:
            time.sleep(1)

    def WaitForInitFor(self, timeoutSec) :
        started = time.time()
        while self.cypher is None and time.time() - started < timeoutSec :
            time.sleep(1)

securityMaster = __SecurityMaster()
securityMaster.start()

def GetSecurityMaster():
    return securityMaster

class __SecuritySession:
    def __init__(self):
        self.transferKey=None
        self.secureKey= None
        self.hideKey=0
        self.cypher=None

__session =__SecuritySession()
def GetSecuritySession() :
    global __session
    return __session

def UpdateNetCypherKey(data):
    global __session
    global securityMaster
    conf = config.GetConfig()
    if conf.CypherLevel > 0 :
        data = GetSecurityMaster().cypher.Decrypt(data)

    in_ = DataInputX(data)

    __session.transferKey = in_.readInt()
    __session.secureKey = in_.readBlob()
    __session.hideKey = in_.read(4)
    __session.cypher = cypher.NewCypher(__session.secureKey, __session.hideKey)
    securityMaster.publicip = in_.readInt()


