#!/usr/bin/python

import lldb
import shlex
import sys
from Tkinter import *
import ttk

class ValueTreeItemDelegate(object):
    def __init__(self, value):
        self.value = value

    def get_item_dictionary(self):
        name = self.value.name
        if name is None:
            name = ''
        typename = self.value.type
        if typename is None:
            typename = ''
        value = self.value.value
        if value is None:
            value = ''
        summary = self.value.summary
        if summary is None:
            summary = ''
        has_children = self.value.MightHaveChildren()
        return { '#0' : name,
                 'typename' : typename,
                 'value' : value,
                 'summary' : summary,
                 'children' : has_children,
                 'tree-item-delegate' : self }
        
    def get_child_item_dictionaries(self):
        item_dicts = list()
        for i in range(self.value.num_children):
            item_delegate = ValueTreeItemDelegate(self.value.GetChildAtIndex(i))
            item_dicts.append(item_delegate.get_item_dictionary())
        return item_dicts

class FrameTreeItemDelegate(object):
    def __init__(self, frame):
        self.frame = frame

    def get_item_dictionary(self):
        id = self.frame.GetFrameID()
        name = 'frame #%u' % (id);
        value = '0x%16.16x' % (self.frame.GetPC())
        stream = lldb.SBStream()
        self.frame.GetDescription(stream)
        summary = stream.GetData().split("`")[1]
        return { '#0' : name,
                 'value': value, 
                 'summary': summary, 
                 'children' : self.frame.GetVariables(True, True, True, True).GetSize() > 0,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        variables = self.frame.GetVariables(True, True, True, True)
        n = variables.GetSize()
        for i in range(n):
            item_delegate = ValueTreeItemDelegate(variables[i])
            item_dicts.append(item_delegate.get_item_dictionary())
        return item_dicts

class ThreadTreeItemDelegate(object):
   def __init__(self, thread):
       self.thread = thread

   def get_item_dictionary(self):
       num_frames = self.thread.GetNumFrames()
       name = 'thread #%u' % (self.thread.GetIndexID())
       value = '0x%x' % (self.thread.GetThreadID())
       summary = '%u frames' % (num_frames)
       return { '#0' : name,
                'value': value, 
                'summary': summary,
                'children' : num_frames > 0,
                'tree-item-delegate' : self }

   def get_child_item_dictionaries(self):
       item_dicts = list()
       for frame in self.thread:
           item_delegate = FrameTreeItemDelegate(frame)
           item_dicts.append(item_delegate.get_item_dictionary())
       return item_dicts
        
class ProcessTreeItemDelegate(object):
    def __init__(self, process):
        self.process = process

    def get_item_dictionary(self):
        id = self.process.GetProcessID()
        num_threads = self.process.GetNumThreads()
        value = str(self.process.GetProcessID())
        summary = self.process.target.executable.fullpath
        return { '#0' : 'process',
                 'value': value, 
                 'summary': summary,
                 'children' : num_threads > 0,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        for thread in self.process:
            item_delegate = ThreadTreeItemDelegate(thread)
            item_dicts.append(item_delegate.get_item_dictionary())
        return item_dicts

class TargetTreeItemDelegate(object):
    def __init__(self, target):
        self.target = target

    def get_item_dictionary(self):
        value = str(self.target.triple)
        summary = self.target.executable.fullpath
        return { '#0' : 'target',
                 'value': value, 
                 'summary': summary,
                 'children' : True,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        image_item_delegate = TargetImagesTreeItemDelegate(self.target)
        item_dicts.append(image_item_delegate.get_item_dictionary())
        return item_dicts

class TargetImagesTreeItemDelegate(object):
    def __init__(self, target):
        self.target = target

    def get_item_dictionary(self):
        value = str(self.target.triple)
        summary = self.target.executable.fullpath
        num_modules = self.target.GetNumModules()
        return { '#0' : 'images',
                 'value': '', 
                 'summary': '%u images' % num_modules,
                 'children' : num_modules > 0,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        for i in range(self.target.GetNumModules()):
            module = self.target.GetModuleAtIndex(i)
            image_item_delegate = ModuleTreeItemDelegate(self.target, module, i)
            item_dicts.append(image_item_delegate.get_item_dictionary())
        return item_dicts

class ModuleTreeItemDelegate(object):
    def __init__(self, target, module, index):
        self.target = target
        self.module = module
        self.index = index

    def get_item_dictionary(self):
        name = 'module %u' % (self.index)
        value = self.module.file.basename
        summary = self.module.file.dirname
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : True,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        sections_item_delegate = ModuleSectionsTreeItemDelegate(self.target, self.module)
        item_dicts.append(sections_item_delegate.get_item_dictionary())

        symbols_item_delegate = ModuleSymbolsTreeItemDelegate(self.target, self.module)
        item_dicts.append(symbols_item_delegate.get_item_dictionary())

        comp_units_item_delegate = ModuleCompileUnitsTreeItemDelegate(self.target, self.module)
        item_dicts.append(comp_units_item_delegate.get_item_dictionary())
        return item_dicts

class ModuleSectionsTreeItemDelegate(object):
    def __init__(self, target, module):
        self.target = target
        self.module = module

    def get_item_dictionary(self):
        name = 'sections'
        value = ''
        summary = '%u sections' % (self.module.GetNumSections())
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : True,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        num_sections = self.module.GetNumSections()
        for i in range(num_sections):
            section = self.module.GetSectionAtIndex(i)
            image_item_delegate = SectionTreeItemDelegate(self.target, section)
            item_dicts.append(image_item_delegate.get_item_dictionary())
        return item_dicts

class SectionTreeItemDelegate(object):
    def __init__(self, target, section):
        self.target = target
        self.section = section

    def get_item_dictionary(self):
        name = self.section.name
        section_load_addr = self.section.GetLoadAddress(self.target)
        if section_load_addr != lldb.LLDB_INVALID_ADDRESS:
            value = '0x%16.16x' % (section_load_addr)
        else:
            value = '0x%16.16x *' % (self.section.file_addr)
        summary = ''
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : self.section.GetNumSubSections() > 0,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        num_sections = self.section.GetNumSubSections()
        for i in range(num_sections):
            section = self.section.GetSubSectionAtIndex(i)
            image_item_delegate = SectionTreeItemDelegate(self.target, section)
            item_dicts.append(image_item_delegate.get_item_dictionary())            
        return item_dicts

class ModuleCompileUnitsTreeItemDelegate(object):
    def __init__(self, target, module):
        self.target = target
        self.module = module

    def get_item_dictionary(self):
        name = 'compile units'
        value = ''
        summary = '%u compile units' % (self.module.GetNumSections())
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : self.module.GetNumCompileUnits() > 0,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        num_cus = self.module.GetNumCompileUnits()
        for i in range(num_cus):
            cu = self.module.GetCompileUnitAtIndex(i)
            image_item_delegate = CompileUnitTreeItemDelegate(self.target, cu)
            item_dicts.append(image_item_delegate.get_item_dictionary())
        return item_dicts

class CompileUnitTreeItemDelegate(object):
    def __init__(self, target, cu):
        self.target = target
        self.cu = cu

    def get_item_dictionary(self):
        name = self.cu.GetFileSpec().basename
        value = ''
        num_lines = self.cu.GetNumLineEntries()
        summary = ''
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : num_lines > 0,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        item_delegate = LineTableTreeItemDelegate(self.target, self.cu)
        item_dicts.append(item_delegate.get_item_dictionary())
        return item_dicts

class LineTableTreeItemDelegate(object):
    def __init__(self, target, cu):
        self.target = target
        self.cu = cu

    def get_item_dictionary(self):
        name = 'line table'
        value = ''
        num_lines = self.cu.GetNumLineEntries()
        summary = '%u line entries' % (num_lines)
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : num_lines > 0,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        num_lines = self.cu.GetNumLineEntries()
        for i in range(num_lines):
            line_entry = self.cu.GetLineEntryAtIndex(i)
            item_delegate = LineEntryTreeItemDelegate(self.target, line_entry, i)
            item_dicts.append(item_delegate.get_item_dictionary())
        return item_dicts

class LineEntryTreeItemDelegate(object):
    def __init__(self, target, line_entry, index):
        self.target = target
        self.line_entry = line_entry
        self.index = index

    def get_item_dictionary(self):
        name = str(self.index)
        address = self.line_entry.GetStartAddress()
        load_addr = address.GetLoadAddress(self.target)
        if load_addr != lldb.LLDB_INVALID_ADDRESS:
            value = '0x%16.16x' % (load_addr)
        else:
            value = '0x%16.16x *' % (address.file_addr)
        summary = self.line_entry.GetFileSpec().fullpath + ':' + str(self.line_entry.line)
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : False,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        return item_dicts

class InstructionTreeItemDelegate(object):
    def __init__(self, target, instr):
        self.target = target
        self.instr = instr

    def get_item_dictionary(self):
        address = self.instr.GetAddress()
        load_addr = address.GetLoadAddress(self.target)
        if load_addr != lldb.LLDB_INVALID_ADDRESS:
            name = '0x%16.16x' % (load_addr)
        else:
            name = '0x%16.16x *' % (address.file_addr)
        value = self.instr.GetMnemonic(self.target) + ' ' + self.instr.GetOperands(self.target)
        summary = self.instr.GetComment(self.target)
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : False,
                 'tree-item-delegate' : self }

class ModuleSymbolsTreeItemDelegate(object):
    def __init__(self, target, module):
        self.target = target
        self.module = module

    def get_item_dictionary(self):
        name = 'symbols'
        value = ''
        summary = '%u symbols' % (self.module.GetNumSymbols())
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : True,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        num_symbols = self.module.GetNumSymbols()
        for i in range(num_symbols):
            symbol = self.module.GetSymbolAtIndex(i)
            image_item_delegate = SymbolTreeItemDelegate(self.target, symbol, i)
            item_dicts.append(image_item_delegate.get_item_dictionary())
        return item_dicts

class SymbolTreeItemDelegate(object):
    def __init__(self, target, symbol, index):
        self.target = target
        self.symbol = symbol
        self.index = index

    def get_item_dictionary(self):
        address = self.symbol.GetStartAddress()
        name = '[%u]' % self.index
        symbol_load_addr = address.GetLoadAddress(self.target)
        if symbol_load_addr != lldb.LLDB_INVALID_ADDRESS:
            value = '0x%16.16x' % (symbol_load_addr)
        else:
            value = '0x%16.16x *' % (address.file_addr)
        summary = self.symbol.name
        return { '#0' : name,
                 'value': value, 
                 'summary': summary,
                 'children' : False,
                 'tree-item-delegate' : self }

    def get_child_item_dictionaries(self):
        item_dicts = list()
        return item_dicts


         
class DelegateTree(ttk.Frame):
     
    def __init__(self, column_dicts, delegate, title, name):
        ttk.Frame.__init__(self, name=name)
        self.pack(expand=Y, fill=BOTH)
        self.master.title(title)
        self.delegate = delegate
        self.columns_dicts = column_dicts
        self.item_id_to_item_dict = dict()
        frame = Frame(self)
        frame.pack(side=TOP, fill=BOTH, expand=Y)
        self._create_treeview(frame)
        self._populate_root()
                     
    def _create_treeview(self, parent):
        frame = ttk.Frame(parent)
        frame.pack(side=TOP, fill=BOTH, expand=Y)
         
        column_ids = list()
        for i in range(1,len(self.columns_dicts)):
            column_ids.append(self.columns_dicts[i]['id'])
        # create the tree and scrollbars
        self.tree = ttk.Treeview(columns=column_ids)
         
        scroll_bar_v = ttk.Scrollbar(orient=VERTICAL, command= self.tree.yview)
        scroll_bar_h = ttk.Scrollbar(orient=HORIZONTAL, command= self.tree.xview)
        self.tree['yscroll'] = scroll_bar_v.set
        self.tree['xscroll'] = scroll_bar_h.set
         
        # setup column headings and columns properties
        for columns_dict in self.columns_dicts:
            self.tree.heading(columns_dict['id'], text=columns_dict['text'], anchor=columns_dict['anchor'])
            self.tree.column(columns_dict['id'], stretch=columns_dict['stretch'])
         
        # add tree and scrollbars to frame
        self.tree.grid(in_=frame, row=0, column=0, sticky=NSEW)
        scroll_bar_v.grid(in_=frame, row=0, column=1, sticky=NS)
        scroll_bar_h.grid(in_=frame, row=1, column=0, sticky=EW)
         
        # set frame resizing priorities
        frame.rowconfigure(0, weight=1)
        frame.columnconfigure(0, weight=1)
         
        # action to perform when a node is expanded
        self.tree.bind('<<TreeviewOpen>>', self._update_tree)

    def insert_items(self, parent_id, item_dicts):
        for item_dict in item_dicts:
            name = None
            values = list()
            first = True
            for columns_dict in self.columns_dicts:
                if first:
                    name = item_dict[columns_dict['id']]
                    first = False
                else:
                    values.append(item_dict[columns_dict['id']])
            item_id = self.tree.insert (parent_id, # root item has an empty name
                                        END, 
                                        text=name, 
                                        values=values)
            self.item_id_to_item_dict[item_id] = item_dict
            if item_dict['children']:
                self.tree.insert(item_id, END, text='dummy')
        
    def _populate_root(self):
        # use current directory as root node
        self.insert_items('', self.delegate.get_child_item_dictionaries())
    
    def _update_tree(self, event):
        # user expanded a node - build the related directory
        item_id = self.tree.focus()      # the id of the expanded node        
        children = self.tree.get_children (item_id)
        if len(children):
            first_child = children[0]
            # if the node only has a 'dummy' child, remove it and
            # build new directory; skip if the node is already
            # populated
            if self.tree.item(first_child, option='text') == 'dummy':
                self.tree.delete(first_child)
                item_dict = self.item_id_to_item_dict[item_id]
                item_dicts = item_dict['tree-item-delegate'].get_child_item_dictionaries()
                self.insert_items(item_id, item_dicts)

@lldb.command("tk-variables")
def tk_variable_display(debugger, command, result, dict):
    sys.argv = ['tk-variables'] # needed for tree creation in TK library as it uses sys.argv...
    target = debugger.GetSelectedTarget()
    if not target:
        print >>result, "invalid target"
        return
    process = target.GetProcess()
    if not process:
        print >>result, "invalid process"
        return
    thread = process.GetSelectedThread()
    if not thread:
        print >>result, "invalid thread"
        return
    frame = thread.GetSelectedFrame()
    if not frame:
        print >>result, "invalid frame"
        return
    # Parse command line args
    command_args = shlex.split(command)
    column_dicts = [{ 'id' : '#0'      , 'text' : 'Name'   , 'anchor' : W , 'stretch' : 0 },
                    { 'id' : 'typename', 'text' : 'Type'   , 'anchor' : W , 'stretch' : 0 },
                    { 'id' : 'value'   , 'text' : 'Value'  , 'anchor' : W , 'stretch' : 0 },
                    { 'id' : 'summary' , 'text' : 'Summary', 'anchor' : W , 'stretch' : 1 }]
    tree = DelegateTree(column_dicts, FrameTreeItemDelegate(frame), 'Variables', 'lldb-tk-variables')
    tree.mainloop()

@lldb.command("tk-process")
def tk_process_display(debugger, command, result, dict):
    sys.argv = ['tk-process'] # needed for tree creation in TK library as it uses sys.argv...
    target = debugger.GetSelectedTarget()
    if not target:
        print >>result, "invalid target"
        return
    process = target.GetProcess()
    if not process:
        print >>result, "invalid process"
        return
    # Parse command line args
    columnd_dicts = [{ 'id' : '#0'     , 'text' : 'Name'   , 'anchor' : W , 'stretch' : 0 },
                     { 'id' : 'value'  , 'text' : 'Value'  , 'anchor' : W , 'stretch' : 0 },
                     { 'id' : 'summary', 'text' : 'Summary', 'anchor' : W , 'stretch' : 1 }];
    command_args = shlex.split(command)
    tree = DelegateTree(columnd_dicts, ProcessTreeItemDelegate(process), 'Process', 'lldb-tk-process')
    tree.mainloop()

@lldb.command("tk-target")
def tk_target_display(debugger, command, result, dict):
    sys.argv = ['tk-target'] # needed for tree creation in TK library as it uses sys.argv...
    target = debugger.GetSelectedTarget()
    if not target:
        print >>result, "invalid target"
        return
    # Parse command line args
    columnd_dicts = [{ 'id' : '#0'     , 'text' : 'Name'   , 'anchor' : W , 'stretch' : 0 },
                     { 'id' : 'value'  , 'text' : 'Value'  , 'anchor' : W , 'stretch' : 0 },
                     { 'id' : 'summary', 'text' : 'Summary', 'anchor' : W , 'stretch' : 1 }];
    command_args = shlex.split(command)
    tree = DelegateTree(columnd_dicts, TargetTreeItemDelegate(target), 'Target', 'lldb-tk-target')
    tree.mainloop()

