#!/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):
    # needed for tree creation in TK library as it uses sys.argv...
    sys.argv = ['tk-variables']
    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):
    # needed for tree creation in TK library as it uses sys.argv...
    sys.argv = ['tk-process']
    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):
    # needed for tree creation in TK library as it uses sys.argv...
    sys.argv = ['tk-target']
    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()
