#!/usr/bin/env python2

import getopt
from gobject import *
import gtk
from tracecmd import *
import time

app = None
data_func_cnt = 0

# In a "real" app these width should be determined at runtime testing max length
# strings in the current font.
TS_COL_W    = 150
CPU_COL_W   = 35
EVENT_COL_W = 150
PID_COL_W   = 75
COMM_COL_W  = 250


def timing(func):
  def wrapper(*arg):
      start = time.time()
      ret = func(*arg)
      end = time.time()
      print '@%s took %0.3f s' % (func.func_name, (end-start))
      return ret
  return wrapper


class EventStore(gtk.GenericTreeModel):
    class EventRef(object):
        '''Inner class to build the trace event index'''
        def __init__(self, index, timestamp, offset, cpu):
            self.index = index
            self.offset = offset
            self.ts = timestamp
            self.cpu = cpu

        def __cmp__(self, other):
            if self.ts < other.ts:
                return -1
            if self.ts > other.ts:
                return 1
            if self.offset < other.offset:
                return -1
            if self.offset > other.offset:
                return 1
            return 0

    # The store only returns the record offset into the trace
    # The view is responsible for looking up the Event with the offset
    column_types = (long,)

    @timing
    def __init__(self, trace):
        gtk.GenericTreeModel.__init__(self)
        self.trace = trace
        self.refs = []
        self._load_trace()
        self._sort()
        self._reindex()

    @timing
    def _load_trace(self):
        print "Building trace index..."
        index = 0
        for cpu in range(0, trace.cpus):
            rec = tracecmd_read_data(self.trace._handle, cpu)
            while rec:
                offset = pevent_record_offset_get(rec)
                ts = pevent_record_ts_get(rec)
                self.refs.append(self.EventRef(index, ts, offset, cpu))
                index = index + 1
                rec = tracecmd_read_data(self.trace._handle, cpu)
        print "Loaded %d events from trace" % (index)

    @timing
    def _sort(self):
        self.refs.sort()

    @timing
    def _reindex(self):
        for i in range(0, len(self.refs)):
            self.refs[i].index = i

    def on_get_flags(self):
        return gtk.TREE_MODEL_LIST_ONLY | gtk.TREE_MODEL_ITERS_PERSIST

    def on_get_n_columns(self):
        return len(self.column_types)

    def on_get_column_type(self, col):
        return self.column_types[col]

    def on_get_iter(self, path):
        return self.refs[path[0]]

    def on_get_path(self, ref):
        return ref.index

    def on_get_value(self, ref, col):
        '''
        The Event record was getting deleted when passed back via this
        method, now it just returns the ref itself. Use get_event() instead.
        '''
        if col == 0:
            #return self.trace.read_event_at(ref.offset)
            return ref
        return None

    def on_iter_next(self, ref):
        try:
            return self.refs[ref.index+1]
        except IndexError:
            return None

    def on_iter_children(self, ref):
        if ref:
            return None
        return self.refs[0]

    def on_iter_has_child(self, ref):
        return False

    def on_iter_n_children(self, ref):
        if ref:
            return 0
        return len(self.refs)

    def on_iter_nth_child(self, ref, n):
        if ref:
            return None
        try:
            return self.refs[n]
        except IndexError:
            return None

    def on_iter_parent(self, child):
        return None

    def get_event(self, iter):
        '''This allocates a record which must be freed by the caller'''
        try:
            ref = self.refs[self.get_path(iter)[0]]
            ev = self.trace.read_event_at(ref.offset)
            return ev
        except IndexError:
            return None


class EventView(gtk.TreeView):
    def __init__(self, model):
        gtk.TreeView.__init__(self, model)
        self.set_fixed_height_mode(True)

        ts_col = gtk.TreeViewColumn("Time (s)")
        ts_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        ts_col.set_fixed_width(TS_COL_W)
        ts_cell = gtk.CellRendererText()
        ts_col.pack_start(ts_cell, False)
        ts_col.set_cell_data_func(ts_cell, self.data_func, "ts")
        self.append_column(ts_col)

        cpu_col = gtk.TreeViewColumn("CPU")
        cpu_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        cpu_col.set_fixed_width(CPU_COL_W)
        cpu_cell = gtk.CellRendererText()
        cpu_col.pack_start(cpu_cell, False)
        cpu_col.set_cell_data_func(cpu_cell, self.data_func, "cpu")
        self.append_column(cpu_col)

        event_col = gtk.TreeViewColumn("Event")
        event_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        event_col.set_fixed_width(EVENT_COL_W)
        event_cell = gtk.CellRendererText()
        event_col.pack_start(event_cell, False)
        event_col.set_cell_data_func(event_cell, self.data_func, "event")
        self.append_column(event_col)

        pid_col = gtk.TreeViewColumn("PID")
        pid_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        pid_col.set_fixed_width(PID_COL_W)
        pid_cell = gtk.CellRendererText()
        pid_col.pack_start(pid_cell, False)
        pid_col.set_cell_data_func(pid_cell, self.data_func, "pid")
        self.append_column(pid_col)

        comm_col = gtk.TreeViewColumn("Comm")
        comm_col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        comm_col.set_fixed_width(COMM_COL_W)
        comm_cell = gtk.CellRendererText()
        comm_col.pack_start(comm_cell, False)
        comm_col.set_cell_data_func(comm_cell, self.data_func, "comm")
        self.append_column(comm_col)

    def data_func(self, col, cell, model, iter, data):
        global app, data_func_cnt

        ev = model.get_event(iter)
        #ev = model.get_value(iter, 0)
        if not ev:
            return False

        if data == "ts":
            cell.set_property("markup", "%d.%d" % (ev.ts/1000000000,
                                                   ev.ts%1000000000))
            data_func_cnt = data_func_cnt + 1
            if app:
                app.inc_data_func()
        elif data == "cpu":
            cell.set_property("markup", ev.cpu)
        elif data == "event":
            cell.set_property("markup", ev.name)
        elif data == "pid":
            cell.set_property("markup", ev.pid)
        elif data == "comm":
            cell.set_property("markup", ev.comm)
        else:
            print "Unknown Column:", data
            return False

        return True


class EventViewerApp(gtk.Window):
    def __init__(self, trace):
        gtk.Window.__init__(self)

        self.set_size_request(650, 400)
        self.set_position(gtk.WIN_POS_CENTER)

        self.connect("destroy", gtk.main_quit)
        self.set_title("Event Viewer")

        store = EventStore(trace)
        view = EventView(store)

        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
        sw.add(view)

        # track how often the treeview data_func is called
        self.data_func_label = gtk.Label("0")
        hbox = gtk.HBox()
        hbox.pack_start(gtk.Label("TS Data Func Calls:"), False, False)
        hbox.pack_start(self.data_func_label, False, False)

        vbox = gtk.VBox()
        vbox.pack_start(hbox, False)
        vbox.pack_end(sw)

        self.add(vbox)
        self.show_all()

    def inc_data_func(self):
        global data_func_cnt
        self.data_func_label.set_text(str(data_func_cnt))


if __name__ == "__main__":
    if len(sys.argv) >=2:
        filename = sys.argv[1]
    else:
        filename = "trace.dat"

    print "Initializing trace..."
    trace = Trace(filename)
    print "Initializing app..."
    app = EventViewerApp(trace)
    print "Go!"
    gtk.main()
