'''
Created on Oct 21, 2018

@author: lqp
'''

import time
import re
import multiprocessing
import resource

current_milli_time = lambda: int(round(time.time() * 1000))

class SystemMetric():
    def __init__(self):
        self.lastCpuTotalTime = -1
        self.lastCpuUseTime = -1
        
        self.lastGetTs = -1
        self.lastInBytes = -1
        self.lastOutBytes = -1
        self.getMetrics({})
        
    def getCpu(self, resDoc):
        with open("/proc/stat", "r") as fo:
            procStatString = fo.readline()
        
        procStats = re.split(r"\s+", procStatString)

        #cpu user, nice, system, idle, iowait, irq, softirq;
        user = int(procStats[1]);
        nice = int(procStats[2]);
        system = int(procStats[3]);
        idle = int(procStats[4]);
        iowait = int(procStats[5]);
        irq = int(procStats[6]);
        softirq = int(procStats[7]);

        cpuTotalTime = user + nice + system + idle + iowait + irq + softirq;

        cpuUseTime = user + nice + system;

        cpuUseRate = 0
        appUseRate = 0
        if self.lastCpuTotalTime == -1:
            self.lastCpuTotalTime = cpuTotalTime;
            self.lastCpuUseTime = cpuUseTime;
        elif cpuTotalTime != self.lastCpuTotalTime:
            cpuUseRate = ((float)(cpuUseTime - self.lastCpuUseTime) /  (cpuTotalTime - self.lastCpuTotalTime)) * 100 * multiprocessing.cpu_count()
            
            self.lastCpuTotalTime = cpuTotalTime;
            self.lastCpuUseTime = cpuUseTime;
        
        resDoc["cpu"] = (int)(appUseRate + 0.5)
        resDoc["devCpu"] = (int)(cpuUseRate + 0.5)
        return resDoc
    
    def getBandwidth(self, resDoc):
        inKB = 0
        outKb = 0
        
        nowTs = current_milli_time()
        with open('/proc/net/netstat', 'r') as fo:
            body = fo.read()
            
        for line in body.split('\n'):
            if re.match(r'IpExt:\s+(\d+)\s', line):
                gs = re.split(r'\s+', line)
                break
        
        if self.lastGetTs == -1 or self.lastInBytes == -1 or self.lastGetTs == nowTs:
            self.lastInBytes = int(gs[7])
            self.lastOutBytes = int(gs[8])
            self.lastGetTs = nowTs
        else:
            nowInBytes = int(gs[7])
            nowOutBytes = int(gs[8])
            
            inKB = (nowInBytes - self.lastInBytes) * 1000.0 / (nowTs - self.lastGetTs) / 1024
            outKb = (nowOutBytes - self.lastOutBytes) * 1000.0 / (nowTs - self.lastGetTs) / 1024
            self.lastInBytes = nowInBytes
            self.lastOutBytes = nowOutBytes
            self.lastGetTs = nowTs
        
        resDoc['devInKB'] = int((inKB + 0.5))
        resDoc['devOutKB'] = int((outKb + 0.5))
        
        return resDoc
    
    def getMetrics(self, resDoc):
        self.getCpu(resDoc)
        self.getBandwidth(resDoc)
        
        return resDoc


if __name__ == '__main__':
    pass