"""
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
"""
# summary provider for NSSet
import lldb
import ctypes
import lldb.runtime.objc.objc_runtime
import lldb.formatters.metrics
import CFBag
import lldb.formatters.Logger

try:
    basestring
except NameError:
    basestring = str

statistics = lldb.formatters.metrics.Metrics()
statistics.add_metric('invalid_isa')
statistics.add_metric('invalid_pointer')
statistics.add_metric('unknown_class')
statistics.add_metric('code_notrun')

# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but the port number of an NSMachPort, so they need not
# obey the interface specification for synthetic children providers


class NSCFSet_SummaryProvider:

    def adjust_for_architecture(self):
        pass

    def __init__(self, valobj, params):
        logger = lldb.formatters.Logger.Logger()
        self.valobj = valobj
        self.sys_params = params
        if not(self.sys_params.types_cache.NSUInteger):
            if self.sys_params.is_64_bit:
                self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
                ).GetBasicType(lldb.eBasicTypeUnsignedLong)
            else:
                self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
                ).GetBasicType(lldb.eBasicTypeUnsignedInt)
        self.update()

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

    # one pointer is the ISA
    # then we have one other internal pointer, plus
    # 4 bytes worth of flags. hence, these values
    def offset(self):
        logger = lldb.formatters.Logger.Logger()
        if self.sys_params.is_64_bit:
            return 20
        else:
            return 12

    def count(self):
        logger = lldb.formatters.Logger.Logger()
        vcount = self.valobj.CreateChildAtOffset(
            "count", self.offset(), self.sys_params.types_cache.NSUInteger)
        return vcount.GetValueAsUnsigned(0)


class NSSetUnknown_SummaryProvider:

    def adjust_for_architecture(self):
        pass

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

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

    def count(self):
        logger = lldb.formatters.Logger.Logger()
        stream = lldb.SBStream()
        self.valobj.GetExpressionPath(stream)
        expr = "(int)[" + stream.GetData() + " count]"
        num_children_vo = self.valobj.CreateValueFromExpression("count", expr)
        if num_children_vo.IsValid():
            return num_children_vo.GetValueAsUnsigned(0)
        return '<variable is not NSSet>'


class NSSetI_SummaryProvider:

    def adjust_for_architecture(self):
        pass

    def __init__(self, valobj, params):
        logger = lldb.formatters.Logger.Logger()
        self.valobj = valobj
        self.sys_params = params
        if not(self.sys_params.types_cache.NSUInteger):
            if self.sys_params.is_64_bit:
                self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
                ).GetBasicType(lldb.eBasicTypeUnsignedLong)
            else:
                self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
                ).GetBasicType(lldb.eBasicTypeUnsignedInt)
        self.update()

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

    # we just need to skip the ISA and the count immediately follows
    def offset(self):
        logger = lldb.formatters.Logger.Logger()
        return self.sys_params.pointer_size

    def count(self):
        logger = lldb.formatters.Logger.Logger()
        num_children_vo = self.valobj.CreateChildAtOffset(
            "count", self.offset(), self.sys_params.types_cache.NSUInteger)
        value = num_children_vo.GetValueAsUnsigned(0)
        if value is not None:
            # the MSB on immutable sets seems to be taken by some other data
            # not sure if it is a bug or some weird sort of feature, but masking it out
            # gets the count right (unless, of course, someone's dictionaries grow
            #                       too large - but I have not tested this)
            if self.sys_params.is_64_bit:
                value = value & ~0xFF00000000000000
            else:
                value = value & ~0xFF000000
        return value


class NSSetM_SummaryProvider:

    def adjust_for_architecture(self):
        pass

    def __init__(self, valobj, params):
        logger = lldb.formatters.Logger.Logger()
        self.valobj = valobj
        self.sys_params = params
        if not(self.sys_params.types_cache.NSUInteger):
            if self.sys_params.is_64_bit:
                self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
                ).GetBasicType(lldb.eBasicTypeUnsignedLong)
            else:
                self.sys_params.types_cache.NSUInteger = self.valobj.GetType(
                ).GetBasicType(lldb.eBasicTypeUnsignedInt)
        self.update()

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

    # we just need to skip the ISA and the count immediately follows
    def offset(self):
        logger = lldb.formatters.Logger.Logger()
        return self.sys_params.pointer_size

    def count(self):
        logger = lldb.formatters.Logger.Logger()
        num_children_vo = self.valobj.CreateChildAtOffset(
            "count", self.offset(), self.sys_params.types_cache.NSUInteger)
        return num_children_vo.GetValueAsUnsigned(0)


class NSCountedSet_SummaryProvider:

    def adjust_for_architecture(self):
        pass

    def __init__(self, valobj, params):
        logger = lldb.formatters.Logger.Logger()
        self.valobj = valobj
        self.sys_params = params
        if not (self.sys_params.types_cache.voidptr):
            self.sys_params.types_cache.voidptr = self.valobj.GetType(
            ).GetBasicType(lldb.eBasicTypeVoid).GetPointerType()
        self.update()

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

    # an NSCountedSet is implemented using a CFBag whose pointer just follows
    # the ISA
    def offset(self):
        logger = lldb.formatters.Logger.Logger()
        return self.sys_params.pointer_size

    def count(self):
        logger = lldb.formatters.Logger.Logger()
        cfbag_vo = self.valobj.CreateChildAtOffset(
            "bag_impl", self.offset(), self.sys_params.types_cache.voidptr)
        return CFBag.CFBagRef_SummaryProvider(
            cfbag_vo, self.sys_params).length()


def GetSummary_Impl(valobj):
    logger = lldb.formatters.Logger.Logger()
    global statistics
    class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
        valobj, statistics)
    if wrapper:
        return wrapper

    name_string = class_data.class_name()
    logger >> "class name is: " + str(name_string)

    if name_string == '__NSCFSet':
        wrapper = NSCFSet_SummaryProvider(valobj, class_data.sys_params)
        statistics.metric_hit('code_notrun', valobj)
    elif name_string == '__NSSetI':
        wrapper = NSSetI_SummaryProvider(valobj, class_data.sys_params)
        statistics.metric_hit('code_notrun', valobj)
    elif name_string == '__NSSetM':
        wrapper = NSSetM_SummaryProvider(valobj, class_data.sys_params)
        statistics.metric_hit('code_notrun', valobj)
    elif name_string == 'NSCountedSet':
        wrapper = NSCountedSet_SummaryProvider(valobj, class_data.sys_params)
        statistics.metric_hit('code_notrun', valobj)
    else:
        wrapper = NSSetUnknown_SummaryProvider(valobj, class_data.sys_params)
        statistics.metric_hit(
            'unknown_class',
            valobj.GetName() +
            " seen as " +
            name_string)
    return wrapper


def NSSet_SummaryProvider(valobj, dict):
    logger = lldb.formatters.Logger.Logger()
    provider = GetSummary_Impl(valobj)
    if provider is not None:
        try:
            summary = provider.count()
        except:
            summary = None
        if summary is None:
            summary = '<variable is not NSSet>'
        if isinstance(summary, basestring):
            return summary
        else:
            summary = str(summary) + \
                (' objects' if summary != 1 else ' object')
        return summary
    return 'Summary Unavailable'


def NSSet_SummaryProvider2(valobj, dict):
    logger = lldb.formatters.Logger.Logger()
    provider = GetSummary_Impl(valobj)
    if provider is not None:
        if isinstance(
                provider,
                lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
            return provider.message()
        try:
            summary = provider.count()
        except:
            summary = None
        logger >> "got summary " + str(summary)
        # for some reason, one needs to clear some bits for the count returned
        # to be correct when using directly CF*SetRef as compared to NS*Set
        # this only happens on 64bit, and the bit mask was derived through
        # experimentation (if counts start looking weird, then most probably
        #                  the mask needs to be changed)
        if summary is None:
            summary = '<variable is not CFSet>'
        if isinstance(summary, basestring):
            return summary
        else:
            if provider.sys_params.is_64_bit:
                summary = summary & ~0x1fff000000000000
            summary = '@"' + str(summary) + \
                (' values"' if summary != 1 else ' value"')
        return summary
    return 'Summary Unavailable'


def __lldb_init_module(debugger, dict):
    debugger.HandleCommand(
        "type summary add -F NSSet.NSSet_SummaryProvider NSSet")
    debugger.HandleCommand(
        "type summary add -F NSSet.NSSet_SummaryProvider2 CFSetRef CFMutableSetRef")
