from sys import version_info

import gdb

if version_info[0] >= 3:
    xrange = range

ZERO_FIELD = "__0"
FIRST_FIELD = "__1"


def unwrap_unique_or_non_null(unique_or_nonnull):
    # BACKCOMPAT: rust 1.32
    # https://github.com/rust-lang/rust/commit/7a0911528058e87d22ea305695f4047572c5e067
    # BACKCOMPAT: rust 1.60
    # https://github.com/rust-lang/rust/commit/2a91eeac1a2d27dd3de1bf55515d765da20fd86f
    ptr = unique_or_nonnull["pointer"]
    return ptr if ptr.type.code == gdb.TYPE_CODE_PTR else ptr[ptr.type.fields()[0]]


# GDB 14 has a tag class that indicates that extension methods are ok
# to call.  Use of this tag only requires that printers hide local
# attributes and methods by prefixing them with "_".
if hasattr(gdb, "ValuePrinter"):
    printer_base = gdb.ValuePrinter
else:
    printer_base = object


class EnumProvider(printer_base):
    def __init__(self, valobj):
        content = valobj[valobj.type.fields()[0]]
        fields = content.type.fields()
        self._empty = len(fields) == 0
        if not self._empty:
            if len(fields) == 1:
                discriminant = 0
            else:
                discriminant = int(content[fields[0]]) + 1
            self._active_variant = content[fields[discriminant]]
            self._name = fields[discriminant].name
            self._full_name = "{}::{}".format(valobj.type.name, self._name)
        else:
            self._full_name = valobj.type.name

    def to_string(self):
        return self._full_name

    def children(self):
        if not self._empty:
            yield self._name, self._active_variant


class StdStringProvider(printer_base):
    def __init__(self, valobj):
        self._valobj = valobj
        vec = valobj["vec"]
        self._length = int(vec["len"])
        self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["inner"]["ptr"])

    def to_string(self):
        return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)

    @staticmethod
    def display_hint():
        return "string"


class StdOsStringProvider(printer_base):
    def __init__(self, valobj):
        self._valobj = valobj
        buf = self._valobj["inner"]["inner"]
        is_windows = "Wtf8Buf" in buf.type.name
        vec = buf["bytes"] if is_windows else buf

        self._length = int(vec["len"])
        self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["inner"]["ptr"])

    def to_string(self):
        return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)

    def display_hint(self):
        return "string"


class StdStrProvider(printer_base):
    def __init__(self, valobj):
        self._valobj = valobj
        self._length = int(valobj["length"])
        self._data_ptr = valobj["data_ptr"]

    def to_string(self):
        return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)

    @staticmethod
    def display_hint():
        return "string"


def _enumerate_array_elements(element_ptrs):
    for i, element_ptr in enumerate(element_ptrs):
        key = "[{}]".format(i)
        element = element_ptr.dereference()

        try:
            # rust-lang/rust#64343: passing deref expr to `str` allows
            # catching exception on garbage pointer
            str(element)
        except RuntimeError:
            yield key, "inaccessible"

            break

        yield key, element


class StdSliceProvider(printer_base):
    def __init__(self, valobj):
        self._valobj = valobj
        self._length = int(valobj["length"])
        self._data_ptr = valobj["data_ptr"]

    def to_string(self):
        return "{}(size={})".format(self._valobj.type, self._length)

    def children(self):
        return _enumerate_array_elements(
            self._data_ptr + index for index in xrange(self._length)
        )

    @staticmethod
    def display_hint():
        return "array"


class StdVecProvider(printer_base):
    def __init__(self, valobj):
        self._valobj = valobj
        self._length = int(valobj["len"])
        self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["inner"]["ptr"])
        ptr_ty = gdb.Type.pointer(valobj.type.template_argument(0))
        self._data_ptr = self._data_ptr.reinterpret_cast(ptr_ty)

    def to_string(self):
        return "Vec(size={})".format(self._length)

    def children(self):
        return _enumerate_array_elements(
            self._data_ptr + index for index in xrange(self._length)
        )

    @staticmethod
    def display_hint():
        return "array"


class StdVecDequeProvider(printer_base):
    def __init__(self, valobj):
        self._valobj = valobj
        self._head = int(valobj["head"])
        self._size = int(valobj["len"])
        # BACKCOMPAT: rust 1.75
        cap = valobj["buf"]["inner"]["cap"]
        if cap.type.code != gdb.TYPE_CODE_INT:
            cap = cap[ZERO_FIELD]
        self._cap = int(cap)
        self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["inner"]["ptr"])
        ptr_ty = gdb.Type.pointer(valobj.type.template_argument(0))
        self._data_ptr = self._data_ptr.reinterpret_cast(ptr_ty)

    def to_string(self):
        return "VecDeque(size={})".format(self._size)

    def children(self):
        return _enumerate_array_elements(
            (self._data_ptr + ((self._head + index) % self._cap))
            for index in xrange(self._size)
        )

    @staticmethod
    def display_hint():
        return "array"


class StdRcProvider(printer_base):
    def __init__(self, valobj, is_atomic=False):
        self._valobj = valobj
        self._is_atomic = is_atomic
        self._ptr = unwrap_unique_or_non_null(valobj["ptr"])
        self._value = self._ptr["data" if is_atomic else "value"]
        self._strong = self._ptr["strong"]["v" if is_atomic else "value"]["value"]
        self._weak = self._ptr["weak"]["v" if is_atomic else "value"]["value"] - 1

    def to_string(self):
        if self._is_atomic:
            return "Arc(strong={}, weak={})".format(int(self._strong), int(self._weak))
        else:
            return "Rc(strong={}, weak={})".format(int(self._strong), int(self._weak))

    def children(self):
        yield "value", self._value
        yield "strong", self._strong
        yield "weak", self._weak


class StdCellProvider(printer_base):
    def __init__(self, valobj):
        self._value = valobj["value"]["value"]

    def to_string(self):
        return "Cell"

    def children(self):
        yield "value", self._value


class StdRefProvider(printer_base):
    def __init__(self, valobj):
        self._value = valobj["value"].dereference()
        self._borrow = valobj["borrow"]["borrow"]["value"]["value"]

    def to_string(self):
        borrow = int(self._borrow)
        if borrow >= 0:
            return "Ref(borrow={})".format(borrow)
        else:
            return "Ref(borrow_mut={})".format(-borrow)

    def children(self):
        yield "*value", self._value
        yield "borrow", self._borrow


class StdRefCellProvider(printer_base):
    def __init__(self, valobj):
        self._value = valobj["value"]["value"]
        self._borrow = valobj["borrow"]["value"]["value"]

    def to_string(self):
        borrow = int(self._borrow)
        if borrow >= 0:
            return "RefCell(borrow={})".format(borrow)
        else:
            return "RefCell(borrow_mut={})".format(-borrow)

    def children(self):
        yield "value", self._value
        yield "borrow", self._borrow


class StdNonZeroNumberProvider(printer_base):
    def __init__(self, valobj):
        fields = valobj.type.fields()
        assert len(fields) == 1
        field = list(fields)[0]

        inner_valobj = valobj[field.name]

        inner_fields = inner_valobj.type.fields()
        assert len(inner_fields) == 1
        inner_field = list(inner_fields)[0]

        self._value = str(inner_valobj[inner_field.name])

    def to_string(self):
        return self._value


# Yields children (in a provider's sense of the word) for a BTreeMap.
def children_of_btree_map(map):
    # Yields each key/value pair in the node and in any child nodes.
    def children_of_node(node_ptr, height):
        def cast_to_internal(node):
            internal_type_name = node.type.target().name.replace(
                "LeafNode", "InternalNode", 1
            )
            internal_type = gdb.lookup_type(internal_type_name)
            return node.cast(internal_type.pointer())

        if node_ptr.type.name.startswith("alloc::collections::btree::node::BoxedNode<"):
            # BACKCOMPAT: rust 1.49
            node_ptr = node_ptr["ptr"]
        node_ptr = unwrap_unique_or_non_null(node_ptr)
        leaf = node_ptr.dereference()
        keys = leaf["keys"]
        vals = leaf["vals"]
        edges = cast_to_internal(node_ptr)["edges"] if height > 0 else None
        length = leaf["len"]

        for i in xrange(0, length + 1):
            if height > 0:
                child_ptr = edges[i]["value"]["value"]
                for child in children_of_node(child_ptr, height - 1):
                    yield child
            if i < length:
                # Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
                key_type_size = keys.type.sizeof
                val_type_size = vals.type.sizeof
                key = (
                    keys[i]["value"]["value"]
                    if key_type_size > 0
                    else gdb.parse_and_eval("()")
                )
                val = (
                    vals[i]["value"]["value"]
                    if val_type_size > 0
                    else gdb.parse_and_eval("()")
                )
                yield key, val

    if map["length"] > 0:
        root = map["root"]
        if root.type.name.startswith("core::option::Option<"):
            root = root.cast(gdb.lookup_type(root.type.name[21:-1]))
        node_ptr = root["node"]
        height = root["height"]
        for child in children_of_node(node_ptr, height):
            yield child


class StdBTreeSetProvider(printer_base):
    def __init__(self, valobj):
        self._valobj = valobj

    def to_string(self):
        return "BTreeSet(size={})".format(self._valobj["map"]["length"])

    def children(self):
        inner_map = self._valobj["map"]
        for i, (child, _) in enumerate(children_of_btree_map(inner_map)):
            yield "[{}]".format(i), child

    @staticmethod
    def display_hint():
        return "array"


class StdBTreeMapProvider(printer_base):
    def __init__(self, valobj):
        self._valobj = valobj

    def to_string(self):
        return "BTreeMap(size={})".format(self._valobj["length"])

    def children(self):
        for i, (key, val) in enumerate(children_of_btree_map(self._valobj)):
            yield "key{}".format(i), key
            yield "val{}".format(i), val

    @staticmethod
    def display_hint():
        return "map"


# BACKCOMPAT: rust 1.35
class StdOldHashMapProvider(printer_base):
    def __init__(self, valobj, show_values=True):
        self._valobj = valobj
        self._show_values = show_values

        self._table = self._valobj["table"]
        self._size = int(self._table["size"])
        self._hashes = self._table["hashes"]
        self._hash_uint_type = self._hashes.type
        self._hash_uint_size = self._hashes.type.sizeof
        self._modulo = 2**self._hash_uint_size
        self._data_ptr = self._hashes[ZERO_FIELD]["pointer"]

        self._capacity_mask = int(self._table["capacity_mask"])
        self._capacity = (self._capacity_mask + 1) % self._modulo

        marker = self._table["marker"].type
        self._pair_type = marker.template_argument(0)
        self._pair_type_size = self._pair_type.sizeof

        self._valid_indices = []
        for idx in range(self._capacity):
            data_ptr = self._data_ptr.cast(self._hash_uint_type.pointer())
            address = data_ptr + idx
            hash_uint = address.dereference()
            hash_ptr = hash_uint[ZERO_FIELD]["pointer"]
            if int(hash_ptr) != 0:
                self._valid_indices.append(idx)

    def to_string(self):
        if self._show_values:
            return "HashMap(size={})".format(self._size)
        else:
            return "HashSet(size={})".format(self._size)

    def children(self):
        start = int(self._data_ptr) & ~1

        hashes = self._hash_uint_size * self._capacity
        align = self._pair_type_size
        len_rounded_up = (
            (
                (((hashes + align) % self._modulo - 1) % self._modulo)
                & ~((align - 1) % self._modulo)
            )
            % self._modulo
            - hashes
        ) % self._modulo

        pairs_offset = hashes + len_rounded_up
        pairs_start = gdb.Value(start + pairs_offset).cast(self._pair_type.pointer())

        for index in range(self._size):
            table_index = self._valid_indices[index]
            idx = table_index & self._capacity_mask
            element = (pairs_start + idx).dereference()
            if self._show_values:
                yield "key{}".format(index), element[ZERO_FIELD]
                yield "val{}".format(index), element[FIRST_FIELD]
            else:
                yield "[{}]".format(index), element[ZERO_FIELD]

    def display_hint(self):
        return "map" if self._show_values else "array"


class StdHashMapProvider(printer_base):
    def __init__(self, valobj, show_values=True):
        self._valobj = valobj
        self._show_values = show_values

        table = self._table()
        table_inner = table["table"]
        capacity = int(table_inner["bucket_mask"]) + 1
        ctrl = table_inner["ctrl"]["pointer"]

        self._size = int(table_inner["items"])
        self._pair_type = table.type.template_argument(0).strip_typedefs()

        self._new_layout = not table_inner.type.has_key("data")
        if self._new_layout:
            self._data_ptr = ctrl.cast(self._pair_type.pointer())
        else:
            self._data_ptr = table_inner["data"]["pointer"]

        self._valid_indices = []
        for idx in range(capacity):
            address = ctrl + idx
            value = address.dereference()
            is_presented = value & 128 == 0
            if is_presented:
                self._valid_indices.append(idx)

    def _table(self):
        if self._show_values:
            hashbrown_hashmap = self._valobj["base"]
        elif self._valobj.type.fields()[0].name == "map":
            # BACKCOMPAT: rust 1.47
            # HashSet wraps std::collections::HashMap, which wraps hashbrown::HashMap
            hashbrown_hashmap = self._valobj["map"]["base"]
        else:
            # HashSet wraps hashbrown::HashSet, which wraps hashbrown::HashMap
            hashbrown_hashmap = self._valobj["base"]["map"]
        return hashbrown_hashmap["table"]

    def to_string(self):
        if self._show_values:
            return "HashMap(size={})".format(self._size)
        else:
            return "HashSet(size={})".format(self._size)

    def children(self):
        pairs_start = self._data_ptr

        for index in range(self._size):
            idx = self._valid_indices[index]
            if self._new_layout:
                idx = -(idx + 1)
            element = (pairs_start + idx).dereference()
            if self._show_values:
                yield "key{}".format(index), element[ZERO_FIELD]
                yield "val{}".format(index), element[FIRST_FIELD]
            else:
                yield "[{}]".format(index), element[ZERO_FIELD]

    def display_hint(self):
        return "map" if self._show_values else "array"
