import time
import whatap.agent.data.data_text as data
from whatap.pack.pack_enum import PackEnum
import whatap.pack.tagcount_pack as tagcount_pack
import whatap.osinfo as osinfo
import whatap.agent.secure.security_master as secure
from whatap.util.hash_util import HashUtil as hashutil
from whatap.value.list_value import ListValue
from whatap.value.null_value import NullValue
import whatap.pack.smnetperf_pack as smnetperf_pack

class TaskInfraNicPerf:
    NIC = "infra_nic_perf"

    NIC_NAME = "name"
    NIC_TOTAL_BITPS = "totalbps"
    NIC_RX_BPS = "rxbps"
    NIC_TX_BPS = "txbps"
    NIC_TOTAL_PPS = "totalpps"
    NIC_RX_PPS = "rxpps"
    NIC_TX_PPS = "txpps"
    NIC_COLLISION = "collision"
    NIC_ERROR_IN = "errIn"
    NIC_ERROR_OUT = "errOut"
    NIC_DROP_IN = "dropIn"
    NIC_DROP_OUT = "dropOut"

    def __init__(self, interval = 5, infra = False, server = True):
        self.intervalValue = interval
        self.recType = 2
        self.infra = infra
        self.server = server

    def interval(self):
        return self.intervalValue

    def process(self, os_, pcode, oid, now):
        netperfs = osinfo.GetNicUtil()
        if not netperfs:
            return None

        infraPack = None
        serverPack = None
        
        if self.infra:
            secu = secure.GetSecurityMaster()
            infraPack = tagcount_pack.TagCountPack()
            infraPack.pcode = pcode
            infraPack.oid = oid
            infraPack.time = now
            infraPack.category = TaskInfraNicPerf.NIC
            infraPack.putTag("oname", str(secu.oname))
            infraPack.putTag("!rectype", str(self.recType))

            idList = ListValue()
            nameList = ListValue()
            totalbpsList = ListValue()
            rxbpsList = ListValue()
            txbpsList = ListValue()
            totalppsList = ListValue()
            rxppsList = ListValue()
            txppsList = ListValue()
            collisionList = ListValue()
            errorInList = ListValue()
            errorOutList = ListValue()
            dropInList = ListValue()
            dropOutList = ListValue()
            linkSpeedList = ListValue()
            linkUsageList = ListValue()

            for netperf in netperfs:
                key = hashutil.hashFromString(netperf.desc)
                idList.addLong(key)
                nameList.addString(netperf.desc)
                rx_bps = netperf.trafficIn
                tx_bps = netperf.trafficOut
                totalbpsList.addFloat(rx_bps + tx_bps)
                rxbpsList.addFloat(rx_bps)
                txbpsList.addFloat(tx_bps)

                totalppsList.addFloat(netperf.packetIn + netperf.packetOut)
                rxppsList.addFloat(netperf.packetIn)
                txppsList.addFloat(netperf.packetOut)
                collisionList.addLong(0)
                errorInList.addFloat(netperf.errorIn)
                errorOutList.addFloat(netperf.errorOut)
                dropInList.addFloat(netperf.droppedIn)
                dropOutList.addFloat(netperf.droppedOut)

                link_speed = osinfo.GetNicLinkSpeed(netperf.desc)
                if link_speed and link_speed > 0:
                    linkSpeedList.addFloat(link_speed)
                    usage = (rx_bps + tx_bps) / link_speed * 100.0
                    linkUsageList.addFloat(min(usage, 100.0))
                else:
                    linkSpeedList.addValue(NullValue())
                    linkUsageList.addValue(NullValue())

            infraPack.put("@id", idList)
            infraPack.put(TaskInfraNicPerf.NIC_NAME, nameList)
            infraPack.put(TaskInfraNicPerf.NIC_TOTAL_BITPS, totalbpsList)
            infraPack.put(TaskInfraNicPerf.NIC_RX_BPS, rxbpsList)
            infraPack.put(TaskInfraNicPerf.NIC_TX_BPS, txbpsList)
            infraPack.put(TaskInfraNicPerf.NIC_TOTAL_PPS, totalppsList)
            infraPack.put(TaskInfraNicPerf.NIC_RX_PPS, rxppsList)
            infraPack.put(TaskInfraNicPerf.NIC_TX_PPS, txppsList)
            infraPack.put(TaskInfraNicPerf.NIC_COLLISION, collisionList)
            infraPack.put(TaskInfraNicPerf.NIC_ERROR_IN, errorInList)
            infraPack.put(TaskInfraNicPerf.NIC_ERROR_OUT, errorOutList)
            infraPack.put(TaskInfraNicPerf.NIC_DROP_IN, dropInList)
            infraPack.put(TaskInfraNicPerf.NIC_DROP_OUT, dropOutList)
            infraPack.put("linkSpeed", linkSpeedList)
            infraPack.put("linkUsage", linkUsageList)

        if self.server:
            serverPack = smnetperf_pack.SMNetPerfPack()
            serverPack.pcode = pcode
            serverPack.oid = oid
            serverPack.time = now
            serverPack.os = os_
            for netperf in netperfs:
                n = smnetperf_pack.NetPerf()
                n.desc = hashutil.hash(netperf.desc)
                data.sendHashText(PackEnum.TEXT_SYS_NET_DESC, n.desc, netperf.desc)
                n.ip = netperf.ip
                n.hwAddr = netperf.hwAddr
                n.trafficIn = netperf.trafficIn
                n.trafficOut = netperf.trafficOut
                n.packetIn = netperf.packetIn
                n.packetOut = netperf.packetOut
                n.errorIn = netperf.errorIn
                n.errorOut =  netperf.errorOut
                n.droppedOut = netperf.droppedOut
                n.droppedIn = netperf.droppedIn
                serverPack.netPerf.append(n)


        return [infraPack, serverPack]




