from __future__ import division
import lldb.formatters.Logger

# C++ STL formatters for LLDB
# As there are many versions of the libcstd++, you are encouraged to look at the STL
# implementation for your platform before relying on these formatters to do the right
# thing for your setup

def ForwardListSummaryProvider(valobj, dict):
    list_capping_size = valobj.GetTarget().GetMaximumNumberOfChildrenToDisplay()
    text = "size=" + str(valobj.GetNumChildren())
    if valobj.GetNumChildren() > list_capping_size:
        return "(capped) " + text
    else:
        return text

def StdOptionalSummaryProvider(valobj, dict):
    has_value = valobj.GetNumChildren() > 0
    # We add wrapping spaces for consistency with the libcxx formatter
    return " Has Value=" + ("true" if has_value else "false") + " "


class StdOptionalSynthProvider:
    def __init__(self, valobj, dict):
        self.valobj = valobj

    def update(self):
        try:
            self.payload = self.valobj.GetChildMemberWithName('_M_payload')
            self.value = self.payload.GetChildMemberWithName('_M_payload')
            self.has_value = self.payload.GetChildMemberWithName('_M_engaged').GetValueAsUnsigned(0) != 0
        except:
            self.has_value = False
        return False


    def num_children(self):
        return 1 if self.has_value else 0

    def get_child_index(self, name):
        return 0

    def get_child_at_index(self, index):
        # some versions of libstdcpp have an additional _M_value child with the actual value
        possible_value = self.value.GetChildMemberWithName('_M_value')
        if possible_value.IsValid():
            return possible_value.Clone('Value')
        return self.value.Clone('Value')

"""
 This formatter can be applied to all
 unordered map-like structures (unordered_map, unordered_multimap, unordered_set, unordered_multiset)
"""
class StdUnorderedMapSynthProvider:
    def __init__(self, valobj, dict):
        self.valobj = valobj
        self.count = None
        self.kind = self.get_object_kind(valobj)

    def get_object_kind(self, valobj):
        type_name = valobj.GetTypeName()
        return "set" if "set" in type_name else "map"

    def extract_type(self):
        type = self.valobj.GetType()
        # type of std::pair<key, value> is the first template
        # argument type of the 4th template argument to std::map and
        # 3rd template argument for std::set. That's why
        # we need to know kind of the object
        template_arg_num = 4 if self.kind == "map" else 3
        allocator_type = type.GetTemplateArgumentType(template_arg_num)
        data_type = allocator_type.GetTemplateArgumentType(0)
        return data_type

    def update(self):
        # preemptively setting this to None - we might end up changing our mind
        # later
        self.count = None
        try:
            self.head = self.valobj.GetChildMemberWithName('_M_h')
            self.before_begin = self.head.GetChildMemberWithName('_M_before_begin')
            self.next = self.before_begin.GetChildMemberWithName('_M_nxt')
            self.data_type = self.extract_type()
            self.skip_size = self.next.GetType().GetByteSize()
            self.data_size = self.data_type.GetByteSize()
            if (not self.data_type.IsValid()) or (not self.next.IsValid()):
                self.count = 0
        except:
            self.count = 0
        return False

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

    def get_child_at_index(self, index):
        logger = lldb.formatters.Logger.Logger()
        logger >> "Being asked to fetch child[" + str(index) + "]"
        if index < 0:
            return None
        if index >= self.num_children():
            return None
        try:
            offset = index
            current = self.next
            while offset > 0:
                current = current.GetChildMemberWithName('_M_nxt')
                offset = offset - 1
            return current.CreateChildAtOffset( '[' + str(index) + ']', self.skip_size, self.data_type)

        except:
            logger >> "Cannot get child"
            return None

    def num_children(self):
        if self.count is None:
            self.count = self.num_children_impl()
        return self.count

    def num_children_impl(self):
        logger = lldb.formatters.Logger.Logger()
        try:
            count = self.head.GetChildMemberWithName('_M_element_count').GetValueAsUnsigned(0)
            return count
        except:
            logger >> "Could not determine the size"
            return 0


class AbstractListSynthProvider:
    def __init__(self, valobj, dict, has_prev):
        '''
        :param valobj: The value object of the list
        :param dict: A dict with metadata provided by LLDB
        :param has_prev: Whether the list supports a 'prev' pointer besides a 'next' one
        '''
        logger = lldb.formatters.Logger.Logger()
        self.valobj = valobj
        self.count = None
        self.has_prev = has_prev
        self.list_capping_size = self.valobj.GetTarget().GetMaximumNumberOfChildrenToDisplay()
        logger >> "Providing synthetic children for a list named " + \
            str(valobj.GetName())

    def next_node(self, node):
        logger = lldb.formatters.Logger.Logger()
        return node.GetChildMemberWithName('_M_next')

    def is_valid(self, node):
        logger = lldb.formatters.Logger.Logger()
        valid = self.value(self.next_node(node)) != self.get_end_of_list_address()
        if valid:
            logger >> "%s is valid" % str(self.valobj.GetName())
        else:
            logger >> "synthetic value is not valid"
        return valid

    def value(self, node):
        logger = lldb.formatters.Logger.Logger()
        value = node.GetValueAsUnsigned()
        logger >> "synthetic value for {}: {}".format(
            str(self.valobj.GetName()), value)
        return value

    # Floyd's cycle-finding algorithm
    # try to detect if this list has a loop
    def has_loop(self):
        global _list_uses_loop_detector
        logger = lldb.formatters.Logger.Logger()
        if not _list_uses_loop_detector:
            logger >> "Asked not to use loop detection"
            return False
        slow = self.next
        fast1 = self.next
        fast2 = self.next
        while self.is_valid(slow):
            slow_value = self.value(slow)
            fast1 = self.next_node(fast2)
            fast2 = self.next_node(fast1)
            if self.value(fast1) == slow_value or self.value(
                    fast2) == slow_value:
                return True
            slow = self.next_node(slow)
        return False

    def num_children(self):
        logger = lldb.formatters.Logger.Logger()
        if self.count is None:
            # libstdc++ 6.0.21 added dedicated count field.
            count_child = self.node.GetChildMemberWithName('_M_data')
            if count_child and count_child.IsValid():
                self.count = count_child.GetValueAsUnsigned(0)
            if self.count is None:
                self.count = self.num_children_impl()
        return self.count

    def num_children_impl(self):
        logger = lldb.formatters.Logger.Logger()
        try:
            # After a std::list has been initialized, both next and prev will
            # be non-NULL
            next_val = self.next.GetValueAsUnsigned(0)
            if next_val == 0:
                return 0
            if self.has_loop():
                return 0
            if self.has_prev:
                prev_val = self.prev.GetValueAsUnsigned(0)
                if prev_val == 0:
                    return 0
                if next_val == self.node_address:
                    return 0
                if next_val == prev_val:
                    return 1
            size = 1
            current = self.next
            while current.GetChildMemberWithName(
                    '_M_next').GetValueAsUnsigned(0) != self.get_end_of_list_address():
                current = current.GetChildMemberWithName('_M_next')
                if not current.IsValid():
                    break
                size = size + 1
                if size >= self.list_capping_size:
                    break

            return size
        except:
            logger >> "Error determining the size"
            return 0

    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 >> "Fetching child " + str(index)
        if index < 0:
            return None
        if index >= self.num_children():
            return None
        try:
            offset = index
            current = self.next
            while offset > 0:
                current = current.GetChildMemberWithName('_M_next')
                offset = offset - 1
            # C++ lists store the data of a node after its pointers. In the case of a forward list, there's just one pointer (next), and
            # in the case of a double-linked list, there's an additional pointer (prev).
            return current.CreateChildAtOffset(
                '[' + str(index) + ']',
               (2 if self.has_prev else 1) * current.GetType().GetByteSize(),
                self.data_type)
        except:
            return None

    def extract_type(self):
        logger = lldb.formatters.Logger.Logger()
        list_type = self.valobj.GetType().GetUnqualifiedType()
        if list_type.IsReferenceType():
            list_type = list_type.GetDereferencedType()
        if list_type.GetNumberOfTemplateArguments() > 0:
            return list_type.GetTemplateArgumentType(0)
        return lldb.SBType()

    def update(self):
        logger = lldb.formatters.Logger.Logger()
        # preemptively setting this to None - we might end up changing our mind
        # later
        self.count = None
        try:
            self.impl = self.valobj.GetChildMemberWithName('_M_impl')
            self.data_type = self.extract_type()
            if (not self.data_type.IsValid()) or (not self.impl.IsValid()):
                self.count = 0
            elif not self.updateNodes():
                self.count = 0
            else:
                self.data_size = self.data_type.GetByteSize()
        except:
            self.count = 0
        return False

    '''
    Method is used to extract the list pointers into the variables (e.g self.node, self.next, and optionally to self.prev)
    and is mandatory to be overriden in each AbstractListSynthProvider subclass.
    This should return True or False depending on wheter it found valid data.
    '''
    def updateNodes(self):
        raise NotImplementedError

    def has_children(self):
        return True

    '''
     Method is used to identify if a node traversal has reached its end
     and is mandatory to be overriden in each AbstractListSynthProvider subclass
    '''
    def get_end_of_list_address(self):
        raise NotImplementedError


class StdForwardListSynthProvider(AbstractListSynthProvider):

    def __init__(self, valobj, dict):
        has_prev = False
        super().__init__(valobj, dict, has_prev)

    def updateNodes(self):
        self.node = self.impl.GetChildMemberWithName('_M_head')
        self.next = self.node.GetChildMemberWithName('_M_next')
        if (not self.node.IsValid()) or (not self.next.IsValid()):
            return False
        return True

    def get_end_of_list_address(self):
        return 0


class StdListSynthProvider(AbstractListSynthProvider):

    def __init__(self, valobj, dict):
        has_prev = True
        super().__init__(valobj, dict, has_prev)

    def updateNodes(self):
        self.node_address = self.valobj.AddressOf().GetValueAsUnsigned(0)
        self.node = self.impl.GetChildMemberWithName('_M_node')
        self.prev = self.node.GetChildMemberWithName('_M_prev')
        self.next = self.node.GetChildMemberWithName('_M_next')
        if self.node_address == 0 or (not self.node.IsValid()) or (not self.next.IsValid()) or (not self.prev.IsValid()):
            return False
        return True

    def get_end_of_list_address(self):
        return self.node_address


class StdVectorSynthProvider:

    class StdVectorImplementation(object):

        def __init__(self, valobj):
            self.valobj = valobj
            self.count = None

        def num_children(self):
            if self.count is None:
                self.count = self.num_children_impl()
            return self.count

        def num_children_impl(self):
            try:
                start_val = self.start.GetValueAsUnsigned(0)
                finish_val = self.finish.GetValueAsUnsigned(0)
                end_val = self.end.GetValueAsUnsigned(0)
                # Before a vector has been constructed, it will contain bad values
                # so we really need to be careful about the length we return since
                # uninitialized data can cause us to return a huge number. We need
                # to also check for any of the start, finish or end of storage values
                # being zero (NULL). If any are, then this vector has not been
                # initialized yet and we should return zero

                # Make sure nothing is NULL
                if start_val == 0 or finish_val == 0 or end_val == 0:
                    return 0
                # Make sure start is less than finish
                if start_val >= finish_val:
                    return 0
                # Make sure finish is less than or equal to end of storage
                if finish_val > end_val:
                    return 0

                # if we have a struct (or other data type that the compiler pads to native word size)
                # this check might fail, unless the sizeof() we get is itself incremented to take the
                # padding bytes into account - on current clang it looks like
                # this is the case
                num_children = (finish_val - start_val)
                if (num_children % self.data_size) != 0:
                    return 0
                else:
                    num_children = num_children // self.data_size
                return num_children
            except:
                return 0

        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
            try:
                offset = index * self.data_size
                return self.start.CreateChildAtOffset(
                    '[' + str(index) + ']', offset, self.data_type)
            except:
                return None

        def update(self):
            # preemptively setting this to None - we might end up changing our
            # mind later
            self.count = None
            try:
                impl = self.valobj.GetChildMemberWithName('_M_impl')
                self.start = impl.GetChildMemberWithName('_M_start')
                self.finish = impl.GetChildMemberWithName('_M_finish')
                self.end = impl.GetChildMemberWithName('_M_end_of_storage')
                self.data_type = self.start.GetType().GetPointeeType()
                self.data_size = self.data_type.GetByteSize()
                # if any of these objects is invalid, it means there is no
                # point in trying to fetch anything
                if self.start.IsValid() and self.finish.IsValid(
                ) and self.end.IsValid() and self.data_type.IsValid():
                    self.count = None
                else:
                    self.count = 0
            except:
                self.count = 0
            return False

    class StdVBoolImplementation(object):

        def __init__(self, valobj, bool_type):
            self.valobj = valobj
            self.bool_type = bool_type
            self.valid = False

        def num_children(self):
            if self.valid:
                start = self.start_p.GetValueAsUnsigned(0)
                finish = self.finish_p.GetValueAsUnsigned(0)
                offset = self.offset.GetValueAsUnsigned(0)
                if finish >= start:
                    return (finish - start) * 8 + offset
            return 0

        def get_child_at_index(self, index):
            if index >= self.num_children():
                return None
            element_type = self.start_p.GetType().GetPointeeType()
            element_bits = 8 * element_type.GetByteSize()
            element_offset = (index // element_bits) * \
                element_type.GetByteSize()
            bit_offset = index % element_bits
            element = self.start_p.CreateChildAtOffset(
                '[' + str(index) + ']', element_offset, element_type)
            bit = element.GetValueAsUnsigned(0) & (1 << bit_offset)
            if bit != 0:
                value_expr = "(bool)true"
            else:
                value_expr = "(bool)false"
            return self.valobj.CreateValueFromExpression(
                "[%d]" % index, value_expr)

        def update(self):
            try:
                m_impl = self.valobj.GetChildMemberWithName('_M_impl')
                self.m_start = m_impl.GetChildMemberWithName('_M_start')
                self.m_finish = m_impl.GetChildMemberWithName('_M_finish')
                self.start_p = self.m_start.GetChildMemberWithName('_M_p')
                self.finish_p = self.m_finish.GetChildMemberWithName('_M_p')
                self.offset = self.m_finish.GetChildMemberWithName('_M_offset')
                if self.offset.IsValid() and self.start_p.IsValid() and self.finish_p.IsValid():
                    self.valid = True
                else:
                    self.valid = False
            except:
                self.valid = False
            return False

    def __init__(self, valobj, dict):
        logger = lldb.formatters.Logger.Logger()
        first_template_arg_type = valobj.GetType().GetTemplateArgumentType(0)
        if str(first_template_arg_type.GetName()) == "bool":
            self.impl = self.StdVBoolImplementation(
                valobj, first_template_arg_type)
        else:
            self.impl = self.StdVectorImplementation(valobj)
        logger >> "Providing synthetic children for a vector named " + \
            str(valobj.GetName())

    def num_children(self):
        return self.impl.num_children()

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

    def get_child_at_index(self, index):
        return self.impl.get_child_at_index(index)

    def update(self):
        return self.impl.update()

    def has_children(self):
        return True

    """
     This formatter can be applied to all
     map-like structures (map, multimap, set, multiset)
    """
class StdMapLikeSynthProvider:

    def __init__(self, valobj, dict):
        logger = lldb.formatters.Logger.Logger()
        self.valobj = valobj
        self.count = None
        self.kind = self.get_object_kind(valobj)
        logger >> "Providing synthetic children for a " + self.kind + " named " + \
            str(valobj.GetName())

    def get_object_kind(self, valobj):
        type_name = valobj.GetTypeName()
        for kind in ["multiset", "multimap", "set", "map"]:
           if kind in type_name:
              return kind
        return type_name

    # we need this function as a temporary workaround for rdar://problem/10801549
    # which prevents us from extracting the std::pair<K,V> SBType out of the template
    # arguments for _Rep_Type _M_t in the object itself - because we have to make up the
    # typename and then find it, we may hit the situation were std::string has multiple
    # names but only one is actually referenced in the debug information. hence, we need
    # to replace the longer versions of std::string with the shorter one in order to be able
    # to find the type name
    def fixup_class_name(self, class_name):
        logger = lldb.formatters.Logger.Logger()
        if class_name == 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >':
            return 'std::basic_string<char>', True
        if class_name == 'basic_string<char, std::char_traits<char>, std::allocator<char> >':
            return 'std::basic_string<char>', True
        if class_name == 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >':
            return 'std::basic_string<char>', True
        if class_name == 'basic_string<char, std::char_traits<char>, std::allocator<char> >':
            return 'std::basic_string<char>', True
        return class_name, False

    def update(self):
        logger = lldb.formatters.Logger.Logger()
        # preemptively setting this to None - we might end up changing our mind
        # later
        self.count = None
        try:
            # we will set this to True if we find out that discovering a node in the object takes more steps than the overall size of the RB tree
            # if this gets set to True, then we will merrily return None for
            # any child from that moment on
            self.garbage = False
            self.Mt = self.valobj.GetChildMemberWithName('_M_t')
            self.Mimpl = self.Mt.GetChildMemberWithName('_M_impl')
            self.Mheader = self.Mimpl.GetChildMemberWithName('_M_header')
            if not self.Mheader.IsValid():
                self.count = 0
            else:
                map_type = self.valobj.GetType()
                if map_type.IsReferenceType():
                    logger >> "Dereferencing type"
                    map_type = map_type.GetDereferencedType()

                # Get the type of std::pair<key, value>. It is the first template
                # argument type of the 4th template argument to std::map.
                allocator_type = map_type.GetTemplateArgumentType(3)
                self.data_type = allocator_type.GetTemplateArgumentType(0)
                if not self.data_type:
                    # GCC does not emit DW_TAG_template_type_parameter for
                    # std::allocator<...>. For such a case, get the type of
                    # std::pair from a member of std::map.
                    rep_type = self.valobj.GetChildMemberWithName('_M_t').GetType()
                    self.data_type = rep_type.GetTypedefedType().GetTemplateArgumentType(1)

                # from libstdc++ implementation of _M_root for rbtree
                self.Mroot = self.Mheader.GetChildMemberWithName('_M_parent')
                self.data_size = self.data_type.GetByteSize()
                self.skip_size = self.Mheader.GetType().GetByteSize()
        except:
            self.count = 0
        return False

    def num_children(self):
        logger = lldb.formatters.Logger.Logger()
        if self.count is None:
            self.count = self.num_children_impl()
        return self.count

    def num_children_impl(self):
        logger = lldb.formatters.Logger.Logger()
        try:
            root_ptr_val = self.node_ptr_value(self.Mroot)
            if root_ptr_val == 0:
                return 0
            count = self.Mimpl.GetChildMemberWithName(
                '_M_node_count').GetValueAsUnsigned(0)
            logger >> "I have " + str(count) + " children available"
            return count
        except:
            return 0

    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 >> "Being asked to fetch child[" + str(index) + "]"
        if index < 0:
            return None
        if index >= self.num_children():
            return None
        if self.garbage:
            logger >> "Returning None since we are a garbage tree"
            return None
        try:
            offset = index
            current = self.left(self.Mheader)
            while offset > 0:
                current = self.increment_node(current)
                offset = offset - 1
            # skip all the base stuff and get at the data
            return current.CreateChildAtOffset(
                '[' + str(index) + ']', self.skip_size, self.data_type)
        except:
            return None

    # utility functions
    def node_ptr_value(self, node):
        logger = lldb.formatters.Logger.Logger()
        return node.GetValueAsUnsigned(0)

    def right(self, node):
        logger = lldb.formatters.Logger.Logger()
        return node.GetChildMemberWithName("_M_right")

    def left(self, node):
        logger = lldb.formatters.Logger.Logger()
        return node.GetChildMemberWithName("_M_left")

    def parent(self, node):
        logger = lldb.formatters.Logger.Logger()
        return node.GetChildMemberWithName("_M_parent")

    # from libstdc++ implementation of iterator for rbtree
    def increment_node(self, node):
        logger = lldb.formatters.Logger.Logger()
        max_steps = self.num_children()
        if self.node_ptr_value(self.right(node)) != 0:
            x = self.right(node)
            max_steps -= 1
            while self.node_ptr_value(self.left(x)) != 0:
                x = self.left(x)
                max_steps -= 1
                logger >> str(max_steps) + " more to go before giving up"
                if max_steps <= 0:
                    self.garbage = True
                    return None
            return x
        else:
            x = node
            y = self.parent(x)
            max_steps -= 1
            while(self.node_ptr_value(x) == self.node_ptr_value(self.right(y))):
                x = y
                y = self.parent(y)
                max_steps -= 1
                logger >> str(max_steps) + " more to go before giving up"
                if max_steps <= 0:
                    self.garbage = True
                    return None
            if self.node_ptr_value(self.right(x)) != self.node_ptr_value(y):
                x = y
            return x

    def has_children(self):
        return True

_list_uses_loop_detector = True
