"""
LLDB AppKit formatters

part of The LLVM Compiler Infrastructure
This file is distributed under the University of Illinois Open Source
License. See LICENSE.TXT for details.
"""
# example synthetic children and summary provider for CFString (and related NSString class)
# the real code is part of the LLDB core
import lldb
import lldb.runtime.objc.objc_runtime
import lldb.formatters.Logger


def CFString_SummaryProvider(valobj, dict):
    logger = lldb.formatters.Logger.Logger()
    provider = CFStringSynthProvider(valobj, dict)
    if not provider.invalid:
        try:
            summary = provider.get_child_at_index(
                provider.get_child_index("content"))
            if isinstance(summary, lldb.SBValue):
                summary = summary.GetSummary()
            else:
                summary = '"' + summary + '"'
        except:
            summary = None
        if summary is None:
            summary = '<variable is not NSString>'
        return '@' + summary
    return ''


def CFAttributedString_SummaryProvider(valobj, dict):
    logger = lldb.formatters.Logger.Logger()
    offset = valobj.GetTarget().GetProcess().GetAddressByteSize()
    pointee = valobj.GetValueAsUnsigned(0)
    summary = '<variable is not NSAttributedString>'
    if pointee is not None and pointee != 0:
        pointee = pointee + offset
        child_ptr = valobj.CreateValueFromAddress(
            "string_ptr", pointee, valobj.GetType())
        child = child_ptr.CreateValueFromAddress(
            "string_data",
            child_ptr.GetValueAsUnsigned(),
            valobj.GetType()).AddressOf()
        provider = CFStringSynthProvider(child, dict)
        if not provider.invalid:
            try:
                summary = provider.get_child_at_index(
                    provider.get_child_index("content")).GetSummary()
            except:
                summary = '<variable is not NSAttributedString>'
    if summary is None:
        summary = '<variable is not NSAttributedString>'
    return '@' + summary


def __lldb_init_module(debugger, dict):
    debugger.HandleCommand(
        "type summary add -F CFString.CFString_SummaryProvider NSString CFStringRef CFMutableStringRef")
    debugger.HandleCommand(
        "type summary add -F CFString.CFAttributedString_SummaryProvider NSAttributedString")


class CFStringSynthProvider:

    def __init__(self, valobj, dict):
        logger = lldb.formatters.Logger.Logger()
        self.valobj = valobj
        self.update()

    # children other than "content" are for debugging only and must not be
    # used in production code
    def num_children(self):
        logger = lldb.formatters.Logger.Logger()
        if self.invalid:
            return 0
        return 6

    def read_unicode(self, pointer, max_len=2048):
        logger = lldb.formatters.Logger.Logger()
        process = self.valobj.GetTarget().GetProcess()
        error = lldb.SBError()
        pystr = u''
        # cannot do the read at once because the length value has
        # a weird encoding. better play it safe here
        while max_len > 0:
            content = process.ReadMemory(pointer, 2, error)
            new_bytes = bytearray(content)
            b0 = new_bytes[0]
            b1 = new_bytes[1]
            pointer = pointer + 2
            if b0 == 0 and b1 == 0:
                break
            # rearrange bytes depending on endianness
            # (do we really need this or is Cocoa going to
            #  use Windows-compatible little-endian even
            #  if the target is big endian?)
            if self.is_little:
                value = b1 * 256 + b0
            else:
                value = b0 * 256 + b1
            pystr = pystr + unichr(value)
            # read max_len unicode values, not max_len bytes
            max_len = max_len - 1
        return pystr

    # handle the special case strings
    # only use the custom code for the tested LP64 case
    def handle_special(self):
        logger = lldb.formatters.Logger.Logger()
        if not self.is_64_bit:
            # for 32bit targets, use safe ObjC code
            return self.handle_unicode_string_safe()
        offset = 12
        pointer = self.valobj.GetValueAsUnsigned(0) + offset
        pystr = self.read_unicode(pointer)
        return self.valobj.CreateValueFromExpression(
            "content", "(char*)\"" + pystr.encode('utf-8') + "\"")

    # last resort call, use ObjC code to read; the final aim is to
    # be able to strip this call away entirely and only do the read
    # ourselves
    def handle_unicode_string_safe(self):
        return self.valobj.CreateValueFromExpression(
            "content", "(char*)\"" + self.valobj.GetObjectDescription() + "\"")

    def handle_unicode_string(self):
        logger = lldb.formatters.Logger.Logger()
        # step 1: find offset
        if self.inline:
            pointer = self.valobj.GetValueAsUnsigned(
                0) + self.size_of_cfruntime_base()
            if not self.explicit:
                # untested, use the safe code path
                return self.handle_unicode_string_safe()
            else:
                # a full pointer is skipped here before getting to the live
                # data
                pointer = pointer + self.pointer_size
        else:
            pointer = self.valobj.GetValueAsUnsigned(
                0) + self.size_of_cfruntime_base()
            # read 8 bytes here and make an address out of them
            try:
                char_type = self.valobj.GetType().GetBasicType(
                    lldb.eBasicTypeChar).GetPointerType()
                vopointer = self.valobj.CreateValueFromAddress(
                    "dummy", pointer, char_type)
                pointer = vopointer.GetValueAsUnsigned(0)
            except:
                return self.valobj.CreateValueFromExpression(
                    "content", '(char*)"@\"invalid NSString\""')
        # step 2: read Unicode data at pointer
        pystr = self.read_unicode(pointer)
        # step 3: return it
        return pystr.encode('utf-8')

    def handle_inline_explicit(self):
        logger = lldb.formatters.Logger.Logger()
        offset = 3 * self.pointer_size
        offset = offset + self.valobj.GetValueAsUnsigned(0)
        return self.valobj.CreateValueFromExpression(
            "content", "(char*)(" + str(offset) + ")")

    def handle_mutable_string(self):
        logger = lldb.formatters.Logger.Logger()
        offset = 2 * self.pointer_size
        data = self.valobj.CreateChildAtOffset(
            "content", offset, self.valobj.GetType().GetBasicType(
                lldb.eBasicTypeChar).GetPointerType())
        data_value = data.GetValueAsUnsigned(0)
        if self.explicit and self.unicode:
            return self.read_unicode(data_value).encode('utf-8')
        else:
            data_value = data_value + 1
            return self.valobj.CreateValueFromExpression(
                "content", "(char*)(" + str(data_value) + ")")

    def handle_UTF8_inline(self):
        logger = lldb.formatters.Logger.Logger()
        offset = self.valobj.GetValueAsUnsigned(
            0) + self.size_of_cfruntime_base()
        if not self.explicit:
            offset = offset + 1
        return self.valobj.CreateValueFromAddress(
            "content", offset, self.valobj.GetType().GetBasicType(
                lldb.eBasicTypeChar)).AddressOf()

    def handle_UTF8_not_inline(self):
        logger = lldb.formatters.Logger.Logger()
        offset = self.size_of_cfruntime_base()
        return self.valobj.CreateChildAtOffset(
            "content", offset, self.valobj.GetType().GetBasicType(
                lldb.eBasicTypeChar).GetPointerType())

    def get_child_at_index(self, index):
        logger = lldb.formatters.Logger.Logger()
        logger >> "Querying for child [" + str(index) + "]"
        if index == 0:
            return self.valobj.CreateValueFromExpression(
                "mutable", str(int(self.mutable)))
        if index == 1:
            return self.valobj.CreateValueFromExpression("inline",
                                                         str(int(self.inline)))
        if index == 2:
            return self.valobj.CreateValueFromExpression(
                "explicit", str(int(self.explicit)))
        if index == 3:
            return self.valobj.CreateValueFromExpression(
                "unicode", str(int(self.unicode)))
        if index == 4:
            return self.valobj.CreateValueFromExpression(
                "special", str(int(self.special)))
        if index == 5:
            # we are handling the several possible combinations of flags.
            # for each known combination we have a function that knows how to
            # go fetch the data from memory instead of running code. if a string is not
            # correctly displayed, one should start by finding a combination of flags that
            # makes it different from these known cases, and provide a new reader function
            # if this is not possible, a new flag might have to be made up (like the "special" flag
            # below, which is not a real flag in CFString), or alternatively one might need to use
            # the ObjC runtime helper to detect the new class and deal with it accordingly
            # print 'mutable = ' + str(self.mutable)
            # print 'inline = ' + str(self.inline)
            # print 'explicit = ' + str(self.explicit)
            # print 'unicode = ' + str(self.unicode)
            # print 'special = ' + str(self.special)
            if self.mutable:
                return self.handle_mutable_string()
            elif self.inline and self.explicit and \
                    self.unicode == False and self.special == False and \
                    self.mutable == False:
                return self.handle_inline_explicit()
            elif self.unicode:
                return self.handle_unicode_string()
            elif self.special:
                return self.handle_special()
            elif self.inline:
                return self.handle_UTF8_inline()
            else:
                return self.handle_UTF8_not_inline()

    def get_child_index(self, name):
        logger = lldb.formatters.Logger.Logger()
        logger >> "Querying for child ['" + str(name) + "']"
        if name == "content":
            return self.num_children() - 1
        if name == "mutable":
            return 0
        if name == "inline":
            return 1
        if name == "explicit":
            return 2
        if name == "unicode":
            return 3
        if name == "special":
            return 4

    # CFRuntimeBase is defined as having an additional
    # 4 bytes (padding?) on LP64 architectures
    # to get its size we add up sizeof(pointer)+4
    # and then add 4 more bytes if we are on a 64bit system
    def size_of_cfruntime_base(self):
        logger = lldb.formatters.Logger.Logger()
        return self.pointer_size + 4 + (4 if self.is_64_bit else 0)

    # the info bits are part of the CFRuntimeBase structure
    # to get at them we have to skip a uintptr_t and then get
    # at the least-significant byte of a 4 byte array. If we are
    # on big-endian this means going to byte 3, if we are on
    # little endian (OSX & iOS), this means reading byte 0
    def offset_of_info_bits(self):
        logger = lldb.formatters.Logger.Logger()
        offset = self.pointer_size
        if not self.is_little:
            offset = offset + 3
        return offset

    def read_info_bits(self):
        logger = lldb.formatters.Logger.Logger()
        cfinfo = self.valobj.CreateChildAtOffset(
            "cfinfo",
            self.offset_of_info_bits(),
            self.valobj.GetType().GetBasicType(
                lldb.eBasicTypeChar))
        cfinfo.SetFormat(11)
        info = cfinfo.GetValue()
        if info is not None:
            self.invalid = False
            return int(info, 0)
        else:
            self.invalid = True
            return None

    # calculating internal flag bits of the CFString object
    # this stuff is defined and discussed in CFString.c
    def is_mutable(self):
        logger = lldb.formatters.Logger.Logger()
        return (self.info_bits & 1) == 1

    def is_inline(self):
        logger = lldb.formatters.Logger.Logger()
        return (self.info_bits & 0x60) == 0

    # this flag's name is ambiguous, it turns out
    # we must skip a length byte to get at the data
    # when this flag is False
    def has_explicit_length(self):
        logger = lldb.formatters.Logger.Logger()
        return (self.info_bits & (1 | 4)) != 4

    # probably a subclass of NSString. obtained this from [str pathExtension]
    # here info_bits = 0 and Unicode data at the start of the padding word
    # in the long run using the isa value might be safer as a way to identify this
    # instead of reading the info_bits
    def is_special_case(self):
        logger = lldb.formatters.Logger.Logger()
        return self.info_bits == 0

    def is_unicode(self):
        logger = lldb.formatters.Logger.Logger()
        return (self.info_bits & 0x10) == 0x10

    # preparing ourselves to read into memory
    # by adjusting architecture-specific info
    def adjust_for_architecture(self):
        logger = lldb.formatters.Logger.Logger()
        self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
        self.is_64_bit = self.pointer_size == 8
        self.is_little = self.valobj.GetTarget().GetProcess(
        ).GetByteOrder() == lldb.eByteOrderLittle

    # reading info bits out of the CFString and computing
    # useful values to get at the real data
    def compute_flags(self):
        logger = lldb.formatters.Logger.Logger()
        self.info_bits = self.read_info_bits()
        if self.info_bits is None:
            return
        self.mutable = self.is_mutable()
        self.inline = self.is_inline()
        self.explicit = self.has_explicit_length()
        self.unicode = self.is_unicode()
        self.special = self.is_special_case()

    def update(self):
        logger = lldb.formatters.Logger.Logger()
        self.adjust_for_architecture()
        self.compute_flags()
