from whatap.pack.pack_enum import PackEnum
from whatap.pack.pack import Pack
from whatap.io.data_outputx import DataOutputX
from whatap.io.data_inputx import DataInputX
from whatap.value.null_value import NullValue
from whatap.value.value_enum import ValueEnum
from whatap.value.text_value import TextValue
from whatap.value.decimal_value import DecimalValue
import whatap.value.value as value
from StringIO import StringIO

OS_LINUX  = 1
OS_WINDOW = 2
OS_OSX    = 3
OS_HPUX   = 4
OS_AIX    = 5
OS_SUNOS  = 6

class SMBasePack(Pack):
    def __init__(self):
        Pack.__init__(self)
        self.ip = None
        self.os = None
        self.cpu = None
        self.cpuCore = None
        self.memory = None
        self.upTime = None
        self.epochTime = None

    def getPackType(self):
        return PackEnum.PACK_SM_BASE

    def write(self, doutx ):
        dout= DataOutputX()
        super(SMBasePack, self).write(dout)
        dout.writeInt(self.ip)
        dout.writeShort(self.os)
        self.cpu.write(dout)
        dout.writeByte(len(self.cpuCore))
        for cpuCore in self.cpuCore:
            cpuCore.write(dout)

        self.memory.write(dout)
        dout.writeDecimal(self.upTime)
        dout.writeLong(self.epochTime)
        doutx.writeBlob(dout.toByteArray())

    def read(self, dinx):
        din= DataInputX(dinx.readBlob())
        super(SMBasePack, self).read(din)
        self.ip = din.readInt()
        self.os = din.readShort()
        if self.os in (OS_LINUX, OS_OSX, OS_AIX, OS_HPUX, OS_SUNOS):
            self.cpu = CpuLinux()
            self.cpu.read(din)
            coreCnt = din.readByte()
            self.cpuCore = []
            for i in range(coreCnt):
                cpuCore = CpuLinux()
                cpuCore.read(din)
                self.cpuCore.append(cpuCore)

            self.memory = MemoryLinux()
            self.memory.read(din)
        elif self.os == OS_WINDOW:
            self.cpu = CpuWindow()
            self.cpu.read(din)
            coreCnt = din.readByte()
            self.cpuCore = []
            for i in range(coreCnt):
                cpuCore = CpuWindow()
                cpuCore.read(din)
                self.cpuCore.append(cpuCore)

            self.memory = MemoryWindow()
            self.memory.read(din)
            self.ypTime = din.readDecimal()
            self.epochTime = din.readLong()

class CpuLinux:
    def __init__(self):
        self.user= None
        self.system= None
        self.idle= None
        self.nice= None
        self.irq= None
        self.softirq= None
        self.steal= None
        self.iowait= None

        self.load1= None
        self.load5= None
        self.load15= None


    def write(self, doutx):
        dout = DataOutputX()
        dout.writeFloat(self.user)
        dout.writeFloat(self.system)
        dout.writeFloat(self.idle)
        dout.writeFloat(self.nice)
        dout.writeFloat(self.irq)
        dout.writeFloat(self.softirq)
        dout.writeFloat(self.steal)
        dout.writeFloat(self.iowait)
        dout.writeFloat(self.load1)
        dout.writeFloat(self.load5)
        dout.writeFloat(self.load15)

        doutx.writeBlob(dout.toByteArray())

    def read(self, dinx ):
        din = DataInputX(dinx.readBlob())
        self.user = din.readFloat()
        self.system = din.readFloat()
        self.idle = din.readFloat()
        self.nice = din.readFloat()
        self.irq = din.readFloat()
        self.softirq = din.readFloat()
        self.steal = din.readFloat()
        self.iowait = din.readFloat()
        self.load1 = din.readFloat()
        self.load5 = din.readFloat()
        self.load15 = din.readFloat()

class CpuWindow :
    def __init__(self):
        self.user = None
        self.system = None
        self.idle  = None
        self.processorQueueLength = None

    def write(self, doutx):
        dout = DataOutputX()
        dout.writeFloat(self.user)
        dout.writeFloat(self.system)
        dout.writeFloat(self.idle)
        dout.writeFloat(self.processorQueueLength)

        doutx.writeBlob(dout.toByteArray())

    def read(self, dinx ):
        din = DataInputX(dinx.readBlob())
        self.user = din.readFloat()
        self.system = din.readFloat()
        self.idle = din.readFloat()
        self.processorQueueLength = din.readFloat()

class MemoryLinux :
    def __init__(self):
        self.total = None
        self.free = None
        self.cached = None
        self.used = None
        self.pused = None
        self.available = None
        self.pavailable = None

        self.buffers = None
        self.shared = None

        self.swapUsed = None
        self.swapPused = None
        self.swapTotal = None

        self.pageFault = None
        self.swapIn = None
        self.swapOut = None
        self.fileSystemIn = None
        self.fileSystemOut = None
        self.scannedPage = None
        self.freedPage = None

    def write(self, doutx):
        dout = DataOutputX()
        dout.writeDecimal(self.total)
        dout.writeDecimal(self.free)
        dout.writeDecimal(self.cached)
        dout.writeDecimal(self.used)
        dout.writeFloat(self.pused)
        dout.writeDecimal(self.available)
        dout.writeFloat(self.pavailable)
    
        dout.writeDecimal(self.buffers)
        dout.writeDecimal(self.shared)
    
        dout.writeDecimal(self.swapUsed)
        dout.writeFloat(self.swapPused)
        dout.writeDecimal(self.swapTotal)
    
        dout.writeFloat(self.pageFault)
    
        doutx.writeBlob(dout.toByteArray())

    def read(self, dinx):
        din = DataInputX(dinx.ReadBlob())
        self.total = din.readDecimal()
        self.free = din.readDecimal()
        self.cached = din.readDecimal()
        self.used = din.readDecimal()
        self.pused = din.readFloat()
        self.available = din.readDecimal()
        self.pavailable = din.readFloat()
    
        self.buffers = din.readDecimal()
        self.shared = din.readDecimal()
    
        self.swapUsed = din.readDecimal()
        self.swapPused = din.readFloat()
        self.swapTotal = din.readDecimal()
    
        self.pageFault = din.readFloat()


class MemoryWindow :
    def __init__(self):
        self.total = None
        self.free = None
        self.cached = None
        self.used = None
        self.pused = None
        self.available = None
        self.pavailable = None
        self.pageFault = None

    def write(self, doutx):
        dout = DataOutputX()
        dout.writeDecimal(self.total)
        dout.writeDecimal(self.free)
        dout.writeDecimal(self.cached)
        dout.writeDecimal(self.used)
        dout.writeFloat(self.pused)
        dout.writeDecimal(self.available)
        dout.writeFloat(self.pavailable)
        dout.writeFloat(self.pageFault)
        doutx.WriteBlob(dout.toByteArray())

    def read(self, dinx):
        din = DataInputX(dinx.ReadBlob())
        self.total = din.readDecimal()
        self.free = din.readDecimal()
        self.cached = din.readDecimal()
        self.used = din.readDecimal()
        self.pused = din.readFloat()
        self.available = din.readDecimal()
        self.pavailable = din.readFloat()
        self.pageFault = din.readFloat()
