"""
LLDB AppKit formatters

Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
See https://llvm.org/LICENSE.txt for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""
# 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

try:
    unichr
except NameError:
    unichr = chr

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()
