import os
import time
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
import whatap.pack.smdisk_pack as smdisk_pack
import whatap.agent.data.data_text as data
from whatap.pack.pack_enum import PackEnum

class TaskInfraFileSystem:
    FILESYSTEM = "infra_filesystem"

    FILESYSTEM_MOUNT_NAME = "mountName"
    FILESYSTEM_TYPE = "fsType"
    FILESYSTEM_USED = "used"
    FILESYSTEM_USAGE = "pUsed"
    FILESYSTEM_FREE = "free"
    FILESYSTEM_PFREE = "pFree"
    FILESYSTEM_INODE = "pInodeUsed"
    FILESYSTEM_TOTALSIZE = "totalSize"
    FILESYSTEM_READ_BPS = "read"
    FILESYSTEM_WRITE_BPS = "write"
    FILESYSTEM_READ_IOPS = "readIops"
    FILESYSTEM_WRITE_IOPS = "writeIops"

    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):
        diskperfs = osinfo.GetDisk()
        if not diskperfs:
            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 = TaskInfraFileSystem.FILESYSTEM
            infraPack.putTag("oname", str(secu.oname))
            infraPack.putTag("!rectype", str(self.recType))

            idList = ListValue()
            mountNameList = ListValue()
            fsTypeList = ListValue()
            usedList = ListValue()
            pUsedList = ListValue()
            freeList = ListValue()
            pFreeList = ListValue()
            pInodeUsedList = ListValue()
            totalSizeList = ListValue()
            readBpsList = ListValue()
            writeBpsList = ListValue()
            readIopsList = ListValue()
            writeIopsList = ListValue()
            devnameList = ListValue()
            ioTotalList = ListValue()
            iopsTotalList = ListValue()

            for diskperf in diskperfs:
                key = hashutil.hashFromString("{}{}".format(diskperf.mountPoint, diskperf.fileSystem))
                idList.addLong(key)
                mountNameList.addString(diskperf.mountPoint)
                fsTypeList.addString(diskperf.fileSystem)
                totalSizeList.addLong(diskperf.totalSpace)
                usedList.addLong(diskperf.usedSpace)
                pUsedList.addFloat(diskperf.usedPercent)
                freeList.addLong(diskperf.freeSpace)
                pFreeList.addFloat(diskperf.freePercent)
                pInodeUsedList.addFloat(diskperf.inodePercent)
                readBpsList.addFloat(diskperf.readBps)
                writeBpsList.addFloat(diskperf.writeBps)
                readIopsList.addFloat(diskperf.readIops)
                writeIopsList.addFloat(diskperf.writeIops)

                try:
                    devname = os.path.basename(os.path.realpath(diskperf.deviceId)) if diskperf.deviceId else ""
                except Exception:
                    devname = diskperf.deviceId if diskperf.deviceId else ""
                devnameList.addString(devname)
                ioTotalList.addFloat(diskperf.readBps + diskperf.writeBps)
                iopsTotalList.addFloat(diskperf.readIops + diskperf.writeIops)

            infraPack.put("@id", idList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_MOUNT_NAME, mountNameList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_TYPE, fsTypeList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_TOTALSIZE, totalSizeList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_USED, usedList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_USAGE, pUsedList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_FREE, freeList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_PFREE, pFreeList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_INODE, pInodeUsedList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_READ_BPS, readBpsList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_WRITE_BPS, writeBpsList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_READ_IOPS, readIopsList)
            infraPack.put(TaskInfraFileSystem.FILESYSTEM_WRITE_IOPS, writeIopsList)
            infraPack.put("devName", devnameList)
            infraPack.put("ioTotal", ioTotalList)
            infraPack.put("iopsTotal", iopsTotalList)
            infraPack.put("IopsTotal", iopsTotalList)



        if self.server:
            serverPack = smdisk_pack.SMDiskPack()
            serverPack.pcode = pcode
            serverPack.oid = oid
            serverPack.time = now
            serverPack.os = os_
            disk = []
            for diskperf in diskperfs:
                p = smdisk_pack.DiskPerf()
                p.blksize = diskperf.blksize
                p.deviceId = hashutil.hash(diskperf.deviceId)
                data.sendHashText(PackEnum.TEXT_SYS_DEVICE_ID, p.deviceId, diskperf.deviceId)
                p.fileSystem = hashutil.hash(diskperf.fileSystem)
                data.sendHashText(PackEnum.TEXT_SYS_FILE_SYSTEM, p.fileSystem, diskperf.fileSystem)
                p.freePercent = diskperf.freePercent
                p.freeSpace = diskperf.freeSpace
                p.mountPoint = hashutil.hash(diskperf.mountPoint)
                data.sendHashText(PackEnum.TEXT_SYS_MOUNT_POINT, p.mountPoint, diskperf.mountPoint)
                p.readBps = diskperf.readBps
                p.readIops = diskperf.readIops
                p.totalSpace = diskperf.totalSpace
                p.usedPercent = diskperf.usedPercent
                p.usedSpace = diskperf.usedSpace
                p.writeBps = diskperf.writeBps
                p.writeIops = diskperf.writeIops
                p.ioPercent = diskperf.ioPercent
                p.queueLength = diskperf.queueLength
                disk.append(p)

            serverPack.disk = disk

        return [infraPack, serverPack]

