#  This file is part of pybootchartgui.

#  pybootchartgui is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.

#  pybootchartgui is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.

#  You should have received a copy of the GNU General Public License
#  along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.


class DiskStatSample:
    def __init__(self, time):
        self.time = time
        self.diskdata = [0, 0, 0]
    def add_diskdata(self, new_diskdata):
        self.diskdata = [ a + b for a, b in zip(self.diskdata, new_diskdata) ]

class CPUSample:
    def __init__(self, time, user, sys, io = 0.0, swap = 0.0):
        self.time = time
        self.user = user
        self.sys = sys
        self.io = io
        self.swap = swap

    @property
    def cpu(self):
        return self.user + self.sys

    def __str__(self):
        return str(self.time) + "\t" + str(self.user) + "\t" + \
               str(self.sys) + "\t" + str(self.io) + "\t" + str (self.swap)

class CPUPressureSample:
    def __init__(self, time, avg10, avg60, avg300, deltaTotal):
        self.time = time
        self.avg10 = avg10
        self.avg60 = avg60
        self.avg300 = avg300
        self.deltaTotal = deltaTotal

class IOPressureSample:
    def __init__(self, time, avg10, avg60, avg300, deltaTotal):
        self.time = time
        self.avg10 = avg10
        self.avg60 = avg60
        self.avg300 = avg300
        self.deltaTotal = deltaTotal


class MemSample:
    used_values = ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree',)

    def __init__(self, time):
        self.time = time
        self.records = {}

    def add_value(self, name, value):
        if name in MemSample.used_values:
            self.records[name] = value

    def valid(self):
        keys = self.records.keys()
        # discard incomplete samples
        return [v for v in MemSample.used_values if v not in keys] == []

class DrawMemSample:
    """
    Condensed version of a MemSample with exactly the values used by the drawing code.
    Initialized either from a valid MemSample or
    a tuple/list of buffer/used/cached/swap values.
    """
    def __init__(self, mem_sample):
        self.time = mem_sample.time
        if isinstance(mem_sample, MemSample):
            self.buffers = mem_sample.records['MemTotal'] - mem_sample.records['MemFree']
            self.used = mem_sample.records['MemTotal'] - mem_sample.records['MemFree'] - mem_sample.records['Buffers']
            self.cached = mem_sample.records['Cached']
            self.swap = mem_sample.records['SwapTotal'] - mem_sample.records['SwapFree']
        else:
            self.buffers, self.used, self.cached, self.swap = mem_sample

class DiskSpaceSample:
    def __init__(self, time):
        self.time = time
        self.records = {}

    def add_value(self, name, value):
        self.records[name] = value

    def valid(self):
        return bool(self.records)

class ProcessSample:
    def __init__(self, time, state, cpu_sample):
        self.time = time
        self.state = state
        self.cpu_sample = cpu_sample

    def __str__(self):
        return str(self.time) + "\t" + str(self.state) + "\t" + str(self.cpu_sample)

class ProcessStats:
    def __init__(self, writer, process_map, sample_count, sample_period, start_time, end_time):
        self.process_map = process_map
        self.sample_count = sample_count
        self.sample_period = sample_period
        self.start_time = start_time
        self.end_time = end_time
        writer.info ("%d samples, avg. sample length %f" % (self.sample_count, self.sample_period))
        writer.info ("process list size: %d" % len (self.process_map.values()))

class Process:
    def __init__(self, writer, pid, cmd, ppid, start_time):
        self.writer = writer
        self.pid = pid
        self.cmd = cmd
        self.exe = cmd
        self.args = []
        self.ppid = ppid
        self.start_time = start_time
        self.duration = 0
        self.samples = []
        self.parent = None
        self.child_list = []

        self.active = None
        self.last_user_cpu_time = None
        self.last_sys_cpu_time = None

        self.last_cpu_ns = 0
        self.last_blkio_delay_ns = 0
        self.last_swapin_delay_ns = 0

    # split this process' run - triggered by a name change
    def split(self, writer, pid, cmd, ppid, start_time):
        split = Process (writer, pid, cmd, ppid, start_time)

        split.last_cpu_ns = self.last_cpu_ns
        split.last_blkio_delay_ns = self.last_blkio_delay_ns
        split.last_swapin_delay_ns = self.last_swapin_delay_ns

        return split

    def __str__(self):
        return " ".join([str(self.pid), self.cmd, str(self.ppid), '[ ' + str(len(self.samples)) + ' samples ]' ])

    def calc_stats(self, samplePeriod):
        if self.samples:
            firstSample = self.samples[0]
            lastSample = self.samples[-1]
            self.start_time = min(firstSample.time, self.start_time)
            self.duration = lastSample.time - self.start_time + samplePeriod

        activeCount = sum( [1 for sample in self.samples if sample.cpu_sample and sample.cpu_sample.sys + sample.cpu_sample.user + sample.cpu_sample.io > 0.0] )
        activeCount = activeCount + sum( [1 for sample in self.samples if sample.state == 'D'] )
        self.active = (activeCount>2)

    def calc_load(self, userCpu, sysCpu, interval):
        userCpuLoad = float(userCpu - self.last_user_cpu_time) / interval
        sysCpuLoad = float(sysCpu - self.last_sys_cpu_time) / interval
        cpuLoad = userCpuLoad + sysCpuLoad
        # normalize
        if cpuLoad > 1.0:
            userCpuLoad = userCpuLoad / cpuLoad
            sysCpuLoad = sysCpuLoad / cpuLoad
        return (userCpuLoad, sysCpuLoad)

    def set_parent(self, processMap):
        if self.ppid != None:
            self.parent = processMap.get (self.ppid)
            if self.parent == None and self.pid // 1000 > 1 and \
                not (self.ppid == 2000 or self.pid == 2000): # kernel threads: ppid=2
                self.writer.warn("Missing CONFIG_PROC_EVENTS: no parent for pid '%i' ('%s') with ppid '%i'" \
                                 % (self.pid,self.cmd,self.ppid))

    def get_end_time(self):
        return self.start_time + self.duration

class DiskSample:
    def __init__(self, time, read, write, util):
        self.time = time
        self.read = read
        self.write = write
        self.util = util
        self.tput = read + write

    def __str__(self):
        return "\t".join([str(self.time), str(self.read), str(self.write), str(self.util)])
