#!/usr/bin/env python

import lldb
import shlex
import sys

from tkinter import *
import tkinter.ttk as 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, END, text=name, values=values  # root item has an empty name
            )
            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()
