#!/usr/bin/env python
from __future__ import print_function

import lldb
import shlex
import sys
try:
    from tkinter import *
    import tkinter.ttk as ttk
except ImportError:
    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("invalid target", file=result)
        return
    process = target.GetProcess()
    if not process:
        print("invalid process", file=result)
        return
    thread = process.GetSelectedThread()
    if not thread:
        print("invalid thread", file=result)
        return
    frame = thread.GetSelectedFrame()
    if not frame:
        print("invalid frame", file=result)
        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("invalid target", file=result)
        return
    process = target.GetProcess()
    if not process:
        print("invalid process", file=result)
        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("invalid target", file=result)
        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()
