import os, time
import socket, fcntl, struct
from whatap.util.hash_util import HashUtil as hash
from whatap.pack.pack_enum import PackEnum
import whatap.pack.smnetperf_pack as smnetperf_pack
import whatap.util.process_util as process_util
from whatap.util.ip_util import IPUtil as ip_util

filesystems = { "btrfs": True, "ext2": True, "ext3": True, "ext4": True, "reiser": True, "xfs": True,
        "ffs": True, "ufs": True, "jfs": True, "jfs2": True, "vxfs": True, "hfs": True, "ntfs": True, "fat32": True,
        "zfs": True, "refs": True, "nfs": True, "nfs2": True, "nfs3": True, "nfs4": True, "cifs": True, "ocfs2": True }

class _NetPerfRaw:
    def __init__(self):
        self.deviceID = None
        self.readCount = None
        self.readByteCount = None
        self.readDroppedCount = None
        self.readErrorCount = None
        self.writeCount = None
        self.writeByteCount = None
        self.writeDroppedCount = None
        self.writeErrorCount = None
        self.timestamp = None

class _NetPerf:
    def __init__(self):
        self.desc = None
        self.ip = None
        self.hwAddr = None
        self.trafficIn = None
        self.trafficOut = None
        self.packetIn = None
        self.packetOut = None
        self.errorIn = None
        self.errorOut =  None
        self.droppedOut = None
        self.droppedIn = None


ip_lookup = {}

def getIp(ifname):
    global ip_lookup
    now = time.time()
    ip = ''
    hwaddr = ''

    if ifname not in ip_lookup or now - ip_lookup[ifname][0] > 300:
        ipinfo = process_util.executeCmd('ip addr show')
        found = False
        for l in ipinfo.split('\n'):
            if l.find(ifname) >= 0:
                found = True
            elif 'mtu' in l.split():
                found = False
            #print 'getIp step -0.1', l, ifname, found

            if found:
                #print 'getIp step -1', l, l.strip().startswith('link/ether')
                if not hwaddr and l.strip().startswith('link/ether'):
                    hwaddr = l.strip().split()[1]
                    #print 'getIp hwaddr:', hwaddr
                if not ip and l.strip().startswith('inet '):

                    ip = ip_util.toBytes(l.strip().split()[1].split('/')[0])

                    #print 'getIp ip:', l.strip().split()[1].split('/')[0]
        ip_lookup[ifname] = (now, ip, hwaddr)
    else:
        _, ip, hwaddr =ip_lookup[ifname]

    return ip, hwaddr


def isPhysical(deviceId):
    try:
        f = open("/sys/class/net/%s/operstate"% deviceId)
        addrAssignType = f.read().strip()
        f.close()

        return addrAssignType == 'up'
    except Exception, e:
        print e
        return False
oldNicTrafficMap = None
def GetNicUtil():
    global oldNicTrafficMap
    try:
        f = open("/proc/net/dev")
        lines = f.readlines()
        f.close()
    except Exception, e:
        return []
    nicTrafficMap = {}

    timestamp = int(time.time() * 1000)
    traffics = []
    j =0
    for line in lines:
        j+=1
        if j < 3:
            continue

        words = line.replace(':',' ').split()
        if len(words) < 13:
            continue
        deviceId = words[0]
        if not isPhysical(deviceId):
            continue

        nicTrafficIoRaw = _NetPerfRaw()
        nicTrafficIoRaw.deviceId = deviceId
        nicTrafficIoRaw.readByteCount = int(words[1])
        nicTrafficIoRaw.readCount = int(words[2])
        nicTrafficIoRaw.readErrorCount = int(words[3])
        nicTrafficIoRaw.readDroppedCount = int(words[4])
        nicTrafficIoRaw.writeByteCount = int(words[9])
        nicTrafficIoRaw.writeCount = int(words[10])
        nicTrafficIoRaw.writeErrorCount = int(words[11])
        nicTrafficIoRaw.writeDroppedCount = int(words[12])
        nicTrafficIoRaw.timestamp = timestamp

        nicTrafficMap[deviceId] = nicTrafficIoRaw 
        if oldNicTrafficMap and deviceId in oldNicTrafficMap:
            oldNicTrafficIoRaw = oldNicTrafficMap[deviceId]
            timediff = nicTrafficIoRaw.timestamp - oldNicTrafficIoRaw.timestamp
            n = _NetPerf()
            n.desc = deviceId
            n.trafficIn = float(nicTrafficIoRaw.readByteCount - oldNicTrafficIoRaw.readByteCount) / timediff * 1000.0 * 8
            n.trafficOut = float(nicTrafficIoRaw.writeByteCount - oldNicTrafficIoRaw.writeByteCount) / timediff * 1000.0 * 8
            n.packetIn = float(nicTrafficIoRaw.readCount - oldNicTrafficIoRaw.readCount) / timediff * 1000.0
            n.packetOut = float(nicTrafficIoRaw.writeCount - oldNicTrafficIoRaw.writeCount) / timediff * 1000.0
            n.droppedIn = float(nicTrafficIoRaw.readDroppedCount - oldNicTrafficIoRaw.readDroppedCount) / timediff * 1000.0
            n.droppedOut = float(nicTrafficIoRaw.writeDroppedCount - oldNicTrafficIoRaw.writeDroppedCount) / timediff * 1000.0
            n.errorIn = float(nicTrafficIoRaw.readErrorCount - oldNicTrafficIoRaw.readErrorCount) / timediff * 1000.0
            n.errorOut = float(nicTrafficIoRaw.writeErrorCount - oldNicTrafficIoRaw.writeErrorCount) / timediff * 1000.0
            n.ip, n.hwAddr = getIp(deviceId)
            traffics.append(n)
    oldNicTrafficMap = nicTrafficMap

    return traffics

def test():
    getDisk()
    time.sleep(5)
    for diskperf in getDisk():
        print [item for item in vars(diskperf).items()]

if __name__ == '__main__':
    test()
