import lldb

_map_capping_size = 255


class libcxx_hash_table_SynthProvider:

    def __init__(self, valobj, dict):
        self.valobj = valobj
        self.num_elements = None
        self.next_element = None
        self.bucket_count = None

    def update(self):
        logger = lldb.formatters.Logger.Logger()
        self.num_elements = None
        self.next_element = None
        self.bucket_count = None
        try:
            # unordered_map is made up of a hash_map, which has 4 pieces in it:
            #   bucket list :
            #      array of buckets
            #   p1 (pair):
            #      first - pointer to first loaded element
            #   p2 (pair):
            #      first - number of elements
            #      second - hash function
            #   p3 (pair):
            #      first - max_load_factor
            #      second - equality operator function
            #
            # For display, we actually don't need to go inside the buckets, since 'p1' has a way to iterate over all
            # the elements directly.
            #
            # We will calculate other values about the map because they will be useful for the summary.
            #
            table = self.valobj.GetChildMemberWithName('__table_')

            bl_ptr = table.GetChildMemberWithName(
                '__bucket_list_').GetChildMemberWithName('__ptr_')
            self.bucket_array_ptr = bl_ptr.GetChildMemberWithName(
                '__first_').GetValueAsUnsigned(0)
            self.bucket_count = bl_ptr.GetChildMemberWithName('__second_').GetChildMemberWithName(
                '__data_').GetChildMemberWithName('__first_').GetValueAsUnsigned(0)
            logger >> "Bucket count = %r" % self.bucket_count

            self.begin_ptr = table.GetChildMemberWithName('__p1_').GetChildMemberWithName(
                '__first_').GetChildMemberWithName('__next_')

            self.num_elements = table.GetChildMemberWithName(
                '__p2_').GetChildMemberWithName('__first_').GetValueAsUnsigned(0)
            self.max_load_factor = table.GetChildMemberWithName(
                '__p3_').GetChildMemberWithName('__first_').GetValueAsUnsigned(0)
            logger >> "Num elements = %r" % self.num_elements

            # save the pointers as we get them
            #   -- don't access this first element if num_element==0!
            self.elements_cache = []
            if self.num_elements:
                self.next_element = self.begin_ptr
            else:
                self.next_element = None
        except Exception as e:
            logger >> "Caught exception: %r" % e
            pass

    def num_children(self):
        global _map_capping_size
        num_elements = self.num_elements
        if num_elements is not None:
            if num_elements > _map_capping_size:
                num_elements = _map_capping_size
        return num_elements

    def has_children(self):
        return True

    def get_child_index(self, name):
        logger = lldb.formatters.Logger.Logger()
        try:
            return int(name.lstrip('[').rstrip(']'))
        except:
            return -1

    def get_child_at_index(self, index):
        logger = lldb.formatters.Logger.Logger()
        logger >> "Retrieving child " + str(index)
        if index < 0:
            return None
        if index >= self.num_children():
            return None

        # extend
        logger >> " : cache size starts with %d elements" % len(
            self.elements_cache)
        while index >= len(self.elements_cache):
            # if we hit the end before we get the index, give up:
            if not self.next_element:
                logger >> " : hit end of list"
                return None

            node = self.next_element.Dereference()

            value = node.GetChildMemberWithName('__value_')
            hash_value = node.GetChildMemberWithName(
                '__hash_').GetValueAsUnsigned()
            self.elements_cache.append((value, hash_value))

            self.next_element = node.GetChildMemberWithName('__next_')
            if not self.next_element.GetValueAsUnsigned(0):
                self.next_element = None

        # hit the index! so we have the value
        logger >> " : cache size ends with %d elements" % len(
            self.elements_cache)
        value, hash_value = self.elements_cache[index]
        return self.valobj.CreateValueFromData(
            '[%d] <hash %d>' %
            (index, hash_value), value.GetData(), value.GetType())


def __lldb_init_module(debugger, dict):
    debugger.HandleCommand(
        'type synthetic add -l unordered_multi.libcxx_hash_table_SynthProvider -x "^(std::__1::)unordered_(multi)?(map|set)<.+> >$" -w libcxx')
