import gdb
import sys

if sys.version_info[0] >= 3:
    long = int


# This is not quite right, as local vars may override symname
def read_global_var(symname):
    return gdb.selected_frame().read_var(symname)


def g_quark_to_string(quark):
    if quark is None:
        return None
    quark = long(quark)
    if quark == 0:
        return None
    try:
        val = read_global_var("quarks")
        max_q = long(read_global_var("quark_seq_id"))
    except Exception:
        try:
            val = read_global_var("g_quarks")
            max_q = long(read_global_var("g_quark_seq_id"))
        except Exception:
            return None
    if quark < max_q:
        return val[quark].string()
    return None


# We override the node printers too, so that node->next is not expanded
class GListNodePrinter:
    "Prints a GList node"

    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "{data=%s, next=0x%x, prev=0x%x}" % (
            str(self.val["data"]),
            long(self.val["next"]),
            long(self.val["prev"]),
        )


class GSListNodePrinter:
    "Prints a GSList node"

    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))


class GListPrinter:
    "Prints a GList"

    class _iterator:
        def __init__(self, head, listtype):
            self.link = head
            self.listtype = listtype
            self.count = 0

        def __iter__(self):
            return self

        def next(self):
            if self.link == 0:
                raise StopIteration
            data = self.link["data"]
            self.link = self.link["next"]
            count = self.count
            self.count = self.count + 1
            return ("[%d]" % count, data)

        __next__ = next

    def __init__(self, val, listtype):
        self.val = val
        self.listtype = listtype

    def children(self):
        return self._iterator(self.val, self.listtype)

    def to_string(self):
        return "0x%x" % (long(self.val))

    def display_hint(self):
        return "array"


class GHashPrinter:
    "Prints a GHashTable"

    class _iterator:
        class _pointer_array:
            def __init__(self, ptr, big_items):
                self._big_items = big_items
                self._gpointer_type = gdb.lookup_type("gpointer")
                item_type = (
                    self._gpointer_type if self._big_items else gdb.lookup_type("guint")
                )

                self._items = ptr.cast(item_type.pointer())

            def __getitem__(self, item):
                item = self._items[item]

                if not self._big_items:
                    item = item.cast(self._gpointer_type)

                return item

        def __init__(self, ht, keys_are_strings):
            self.ht = ht
            if ht != 0:
                self.keys = self._pointer_array(ht["keys"], ht["have_big_keys"])
                self.values = self._pointer_array(ht["values"], ht["have_big_values"])
                self.hashes = ht["hashes"]
                self.size = ht["size"]
            self.pos = 0
            self.keys_are_strings = keys_are_strings
            self.value = None

        def __iter__(self):
            return self

        def next(self):
            if self.ht == 0:
                raise StopIteration
            if self.value is not None:
                v = self.value
                self.value = None
                return v
            while long(self.pos) < long(self.size):
                if long(self.hashes[self.pos]) >= 2:
                    key = self.keys[self.pos]
                    val = self.values[self.pos]

                    if self.keys_are_strings:
                        key = key.cast(gdb.lookup_type("char").pointer())

                    # Queue value for next result
                    self.value = ("[%dv]" % (self.pos), val)

                    # Increment pos and return key
                    key = ("[%dk]" % (self.pos), key)
                    self.pos += 1
                    return key

                self.pos += 1
            raise StopIteration

        __next__ = next

    def __init__(self, val):
        self.val = val
        self.keys_are_strings = False
        try:
            string_hash = read_global_var("g_str_hash")
        except Exception:
            string_hash = None
        if (
            self.val != 0
            and string_hash is not None
            and self.val["hash_func"] == string_hash
        ):
            self.keys_are_strings = True

    def children(self):
        return self._iterator(self.val, self.keys_are_strings)

    def to_string(self):
        return "0x%x" % (long(self.val))

    def display_hint(self):
        return "map"


def pretty_printer_lookup(val):
    # None yet, want things like hash table and list

    type = val.type.unqualified()

    # If it points to a reference, get the reference.
    if type.code == gdb.TYPE_CODE_REF:
        type = type.target()

    if type.code == gdb.TYPE_CODE_PTR:
        type = type.target().unqualified()
        t = str(type)
        if t == "GList":
            return GListPrinter(val, "GList")
        if t == "GSList":
            return GListPrinter(val, "GSList")
        if t == "GHashTable":
            return GHashPrinter(val)
    else:
        t = str(type)
        if t == "GList":
            return GListNodePrinter(val)
        if t == "GSList *":
            return GListPrinter(val, "GSList")
    return None


def register(obj):
    if obj is None:
        obj = gdb

    obj.pretty_printers.append(pretty_printer_lookup)


class ForeachCommand(gdb.Command):
    """Foreach on list"""

    def __init__(self):
        super(ForeachCommand, self).__init__(
            "gforeach", gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL
        )

    def valid_name(self, name):
        if not name[0].isalpha():
            return False
        return True

    def parse_args(self, arg):
        i = arg.find(" ")
        if i <= 0:
            raise Exception("No var specified")
        var = arg[:i]
        if not self.valid_name(var):
            raise Exception("Invalid variable name")

        while i < len(arg) and arg[i].isspace():
            i = i + 1

        if arg[i : i + 2] != "in":
            raise Exception("Invalid syntax, missing in")

        i = i + 2

        while i < len(arg) and arg[i].isspace():
            i = i + 1

        colon = arg.find(":", i)
        if colon == -1:
            raise Exception("Invalid syntax, missing colon")

        val = arg[i:colon]

        colon = colon + 1
        while colon < len(arg) and arg[colon].isspace():
            colon = colon + 1

        command = arg[colon:]

        return (var, val, command)

    def do_iter(self, arg, item, command):
        item = item.cast(gdb.lookup_type("void").pointer())
        item = long(item)
        to_eval = "set $%s = (void *)0x%x\n" % (arg, item)
        gdb.execute(to_eval)
        gdb.execute(command)

    def slist_iterator(self, arg, container, command):
        list_element = container.cast(gdb.lookup_type("GSList").pointer())
        while long(list_element) != 0:
            self.do_iter(arg, list_element["data"], command)
            list_element = list_element["next"]

    def list_iterator(self, arg, container, command):
        list_element = container.cast(gdb.lookup_type("GList").pointer())
        while long(list_element) != 0:
            self.do_iter(arg, list_element["data"], command)
            list_element = list_element["next"]

    def pick_iterator(self, container):
        t = container.type.unqualified()
        if t.code == gdb.TYPE_CODE_PTR:
            t = t.target().unqualified()
            t = str(t)
            if t == "GSList":
                return self.slist_iterator
            if t == "GList":
                return self.list_iterator
        raise Exception("Invalid container type %s" % (str(container.type)))

    def invoke(self, arg, from_tty):
        (var, container, command) = self.parse_args(arg)
        container = gdb.parse_and_eval(container)
        func = self.pick_iterator(container)
        func(var, container, command)


ForeachCommand()
