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 

class TaskInfraProcessTopNAndGroup:
    PROCESS_TOPN = "infra_process_topn"

    PROCESS_TOPN_COMMAND = "cmd"
    PROCESS_TOPN_OWNER = "owner"
    PROCESS_TOPN_CMDLINE = "args"
    PROCESS_TOPN_STIME = "stime"
    PROCESS_TOPN_PID = "pid"
    PROCESS_TOPN_PPID = "ppid"
    PROCESS_TOPN_CPU = "cpu"
    PROCESS_TOPN_RSS = "rss"
    PROCESS_TOPN_VSZ = "vsz"
    PROCESS_TOPN_TOTAL_CHAR_IO = "totalCharIo"
    PROCESS_TOPN_THREAD_COUNT = "threadCnt"
    PROCESS_TOPN_PROCESSINFO = "procInfo"

    PROCESS_GROUP = "infra_process_group"
    PROCESS_GROUP_COMMAND = "cmd"
    PROCESS_GROUP_OWNER = "owner"
    PROCESS_GROUP_CPU = "cpu"
    PROCESS_GROUP_RSS = "rss"
    PROCESS_GROUP_VSZ = "vsz"
    PROCESS_GROUP_TOTAL_CHAR_IO = "totalCharIo"
    PROCESS_GROUP_THREAD_COUNT = "threadCnt"
    PROCESS_GROUP_PROCESS_COUNT = "procCnt"


    def __init__(self, interval = 5, topn = 40):
        self.intervalValue = interval
        self.recType = 2
        self.topn = topn

    def interval(self):
        return self.intervalValue

    def process(self, os_, pcode, oid, now):
        (topn, pg) = osinfo.GetTopNAndGroupProc(self.topn)
        topnPack = None
        pgPack = None

        secu = secure.GetSecurityMaster()
        if topn:
            topnPack = tagcount_pack.TagCountPack()
            topnPack.pcode = pcode
            topnPack.oid = oid
            topnPack.time = now
            topnPack.category = TaskInfraProcessTopNAndGroup.PROCESS_TOPN
            topnPack.putTag("oname", str(secu.oname))
            topnPack.putTag("!rectype", str(self.recType))

        
            idList = ListValue()
            commandList = ListValue()
            ownerList = ListValue()
            cmdlineList = ListValue()
            stimeList = ListValue()
            pidList = ListValue()
            ppidList = ListValue()
            cpuList = ListValue()
            rssList = ListValue()
            vszList = ListValue()
            totalCharIoList = ListValue()
            threadCountList = ListValue()
            processInfoList = ListValue()

            for proc in topn:
                key = hashutil.hashFromString("{}{}{}{}{}{}".format(proc.cmd1, proc.user, proc.cmd2, proc.createTime, proc.pid, proc.ppid))
                idList.addLong(key)
                commandList.addString(proc.cmd1)
                ownerList.addString(proc.user)
                cmdlineList.addString(proc.cmd2)
                stimeList.addLong(proc.createTime)
                pidList.addLong(proc.pid)
                ppidList.addLong(proc.ppid)
                cpuList.addFloat(proc.cpu)
                rssList.addLong(proc.memoryBytes)
                vszList.addLong(proc.vsz)
                totalCharIoList.addFloat(proc.totalCharIO)
                threadCountList.addLong(proc.threadCount)
                processInfoList.addString("{}, {}, {}, {}, {} ({})".format(proc.user, proc.pid, proc.ppid, proc.createTime, proc.cmd1, proc.cmd2))

            topnPack.put("@id", idList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_COMMAND, commandList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_OWNER, ownerList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_CMDLINE, cmdlineList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_STIME, stimeList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_PID, pidList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_PPID, ppidList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_CPU, cpuList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_RSS, rssList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_VSZ, vszList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_TOTAL_CHAR_IO, totalCharIoList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_THREAD_COUNT, threadCountList)
            topnPack.put(TaskInfraProcessTopNAndGroup.PROCESS_TOPN_PROCESSINFO, processInfoList)

        if pg:
            pgPack = tagcount_pack.TagCountPack()
            pgPack.pcode = pcode
            pgPack.oid = oid
            pgPack.time = now
            pgPack.category = TaskInfraProcessTopNAndGroup.PROCESS_GROUP
            pgPack.putTag("oname", str(secu.oname))
            pgPack.putTag("!rectype", str(self.recType))

            idList = ListValue()
            commandList = ListValue()
            ownerList = ListValue()
            cpuList = ListValue()
            rssList = ListValue()
            vszList = ListValue()
            totalCharIoList = ListValue()
            threadCountList = ListValue()
            processCountList = ListValue()

            for key, proc in pg.items():
                key = hashutil.hashFromString("{}{}".format(proc.cmd1, proc.user))
                idList.addLong(key)
                commandList.addString(proc.cmd1)
                ownerList.addString(proc.user)
                cpuList.addFloat(proc.cpu)
                rssList.addLong(proc.memoryBytes)
                vszList.addLong(proc.vsz)
                totalCharIoList.addFloat(proc.totalCharIO)
                threadCountList.addLong(proc.threadCount)
                processCountList.addLong(proc.processCount)

            pgPack.put("@id", idList)
            pgPack.put(TaskInfraProcessTopNAndGroup.PROCESS_GROUP_COMMAND, commandList)
            pgPack.put(TaskInfraProcessTopNAndGroup.PROCESS_GROUP_OWNER, ownerList)
            pgPack.put(TaskInfraProcessTopNAndGroup.PROCESS_GROUP_CPU, cpuList)
            pgPack.put(TaskInfraProcessTopNAndGroup.PROCESS_GROUP_RSS, rssList)
            pgPack.put(TaskInfraProcessTopNAndGroup.PROCESS_GROUP_VSZ, vszList)
            pgPack.put(TaskInfraProcessTopNAndGroup.PROCESS_GROUP_TOTAL_CHAR_IO, totalCharIoList)
            pgPack.put(TaskInfraProcessTopNAndGroup.PROCESS_GROUP_THREAD_COUNT, threadCountList)
            pgPack.put(TaskInfraProcessTopNAndGroup.PROCESS_GROUP_PROCESS_COUNT, processCountList)


        return [topnPack, pgPack]


