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


class TaskInfraZpoolPerf:
    CATEGORY = "infra_zpool_perf"

    FIELD_NAME = "name"
    FIELD_POOL_NAME = "poolName"
    FIELD_DEV_NAME = "devName"
    FIELD_DEV_TYPE = "devType"
    FIELD_ALLOCATED = "allocated"
    FIELD_FREE = "free"
    FIELD_TOTAL = "total"
    FIELD_PCT_USED = "pctUsed"
    FIELD_READ_BYTES = "readBytes"
    FIELD_WRITE_BYTES = "writeBytes"
    FIELD_TOTAL_BYTES = "totalBytes"
    FIELD_READ_OPS = "readOperation"
    FIELD_WRITE_OPS = "writeOperation"
    FIELD_TOTAL_OPS = "totalOperation"

    def __init__(self, interval=5):
        self.init = osinfo.InitZfsInfo()
        self.intervalValue = interval
        self.recType = 2

    def interval(self):
        return self.intervalValue

    def process(self, os_, pcode, oid, now):
        if not self.init:
            return None

        perf_list = osinfo.GetZpoolPerfInfo()
        if not perf_list:
            return None

        secu = secure.GetSecurityMaster()
        p = tagcount_pack.TagCountPack()
        p.pcode = pcode
        p.oid = oid
        p.time = now
        p.category = TaskInfraZpoolPerf.CATEGORY
        p.putTag("oname", str(secu.oname))
        p.putTag("!rectype", str(self.recType))

        idList = ListValue()
        nameList = ListValue()
        poolNameList = ListValue()
        devNameList = ListValue()
        devTypeList = ListValue()
        allocatedList = ListValue()
        freeList = ListValue()
        totalList = ListValue()
        pctUsedList = ListValue()
        readBytesList = ListValue()
        writeBytesList = ListValue()
        totalBytesList = ListValue()
        readOpsList = ListValue()
        writeOpsList = ListValue()
        totalOpsList = ListValue()

        for perf in perf_list:
            key = hashutil.hashFromString("{}{}".format(perf.name, perf.devType))
            idList.addLong(key)
            nameList.addString(perf.name)
            poolNameList.addString(perf.poolName if perf.poolName else perf.name)
            devNameList.addString(perf.devName if perf.devName else perf.name)
            devTypeList.addString(perf.devType if perf.devType else "data")
            allocatedList.addLong(long(perf.allocated))
            freeList.addLong(long(perf.free))
            totalList.addLong(long(perf.total))
            pctUsedList.addFloat(float(perf.pctUsed))
            readBytesList.addFloat(float(perf.readBytes) / 1024.0)
            writeBytesList.addFloat(float(perf.writeBytes) / 1024.0)
            totalBytesList.addFloat(float(perf.readBytes + perf.writeBytes) / 1024.0)
            readOpsList.addFloat(float(perf.readOps))
            writeOpsList.addFloat(float(perf.writeOps))
            totalOpsList.addFloat(float(perf.readOps + perf.writeOps))

        p.put("@id", idList)
        p.put(TaskInfraZpoolPerf.FIELD_NAME, nameList)
        p.put(TaskInfraZpoolPerf.FIELD_POOL_NAME, poolNameList)
        p.put(TaskInfraZpoolPerf.FIELD_DEV_NAME, devNameList)
        p.put(TaskInfraZpoolPerf.FIELD_DEV_TYPE, devTypeList)
        p.put(TaskInfraZpoolPerf.FIELD_ALLOCATED, allocatedList)
        p.put(TaskInfraZpoolPerf.FIELD_FREE, freeList)
        p.put(TaskInfraZpoolPerf.FIELD_TOTAL, totalList)
        p.put(TaskInfraZpoolPerf.FIELD_PCT_USED, pctUsedList)
        p.put(TaskInfraZpoolPerf.FIELD_READ_BYTES, readBytesList)
        p.put(TaskInfraZpoolPerf.FIELD_WRITE_BYTES, writeBytesList)
        p.put(TaskInfraZpoolPerf.FIELD_TOTAL_BYTES, totalBytesList)
        p.put(TaskInfraZpoolPerf.FIELD_READ_OPS, readOpsList)
        p.put(TaskInfraZpoolPerf.FIELD_WRITE_OPS, writeOpsList)
        p.put(TaskInfraZpoolPerf.FIELD_TOTAL_OPS, totalOpsList)

        return p
