# Copyright 2022 The Dawn & Tint Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Pretty printers for the Tint project.
#
# If using lldb from command line, add a line to your ~/.lldbinit to import the printers:
#
#    command script import /path/to/dawn/src/tint/tint_lldb.py
#
#
# If using VS Code on MacOS with the Microsoft C/C++ extension, add the following to
# your launch.json (make sure you specify an absolute path to tint_lldb.py):
#
#    "name": "Launch",
#    "type": "cppdbg",
#    "request": "launch",
#    ...
#    "setupCommands": [
#        {
#            "description": "Load tint pretty printers",
#            "ignoreFailures": false,
#            "text": "command script import /path/to/dawn/src/tint/tint_lldb.py,
#        }
#    ]
#
# If using VS Code with the CodeLLDB extension (https://github.com/vadimcn/vscode-lldb),
# add the following to your launch.json:
#
#    "name": "Launch",
#    "type": "lldb",
#    "request": "launch",
#    ...
#    "initCommands": [
#        "command script import /path/to/dawn/src/tint/tint_lldb.py"
#    ]

# Based on pretty printers for:
# Rust: https://github.com/vadimcn/vscode-lldb/blob/master/formatters/rust.py
# Dlang: https://github.com/Pure-D/dlang-debug/blob/master/lldb_dlang.py
#
#
# Tips for debugging using VS Code:
#
# - Set a breakpoint where you can view the types you want to debug/write pretty printers for.
# - Debug Console: -exec command script import /path/to/dawn/src/tint/tint_lldb.py
# - You can re-run the above command to reload the printers after modifying the python script.

# - Useful docs:
#   Formattesr: https://lldb.llvm.org/use/variable.html
#   Python API: https://lldb.llvm.org/python_api.html
#   Especially:
#     SBType: https://lldb.llvm.org/python_api/lldb.SBType.html
#     SBValue: https://lldb.llvm.org/python_api/lldb.SBValue.html

from __future__ import print_function, division
import sys
import logging
import re
import lldb
import types

if sys.version_info[0] == 2:
    # python2-based LLDB accepts utf8-encoded ascii strings only.
    def to_lldb_str(s):
        return s.encode('utf8', 'backslashreplace') if isinstance(
            s, unicode) else s

    range = xrange
else:
    to_lldb_str = str

string_encoding = "escape"  # remove | unicode | escape

log = logging.getLogger(__name__)

module = sys.modules[__name__]
tint_category = None


def __lldb_init_module(debugger, dict):
    global tint_category

    tint_category = debugger.CreateCategory('tint')
    tint_category.SetEnabled(True)

    attach_synthetic_to_type(UtilsSlicePrinter, r'^tint::Slice<.+>$', True)

    attach_synthetic_to_type(UtilsVectorPrinter, r'^tint::Vector<.+>$', True)

    attach_synthetic_to_type(UtilsVectorRefPrinter, r'^tint::VectorRef<.+>$',
                             True)

    attach_synthetic_to_type(UtilsHashsetPrinter, r'^tint::Hashset<.+>$', True)

    attach_synthetic_to_type(UtilsHashmapPrinter, r'^tint::Hashmap<.+>$', True)


def attach_synthetic_to_type(synth_class, type_name, is_regex=False):
    global module, tint_category
    synth = lldb.SBTypeSynthetic.CreateWithClassName(__name__ + '.' +
                                                     synth_class.__name__)
    synth.SetOptions(lldb.eTypeOptionCascade)
    ret = tint_category.AddTypeSynthetic(
        lldb.SBTypeNameSpecifier(type_name, is_regex), synth)
    log.debug('attaching synthetic %s to "%s", is_regex=%s -> %s',
              synth_class.__name__, type_name, is_regex, ret)

    def summary_fn(valobj, dict):
        return get_synth_summary(synth_class, valobj, dict)

    # LLDB accesses summary fn's by name, so we need to create a unique one.
    summary_fn.__name__ = '_get_synth_summary_' + synth_class.__name__
    setattr(module, summary_fn.__name__, summary_fn)
    attach_summary_to_type(summary_fn, type_name, is_regex)


def attach_summary_to_type(summary_fn, type_name, is_regex=False):
    global module, tint_category
    summary = lldb.SBTypeSummary.CreateWithFunctionName(__name__ + '.' +
                                                        summary_fn.__name__)
    summary.SetOptions(lldb.eTypeOptionCascade)
    ret = tint_category.AddTypeSummary(
        lldb.SBTypeNameSpecifier(type_name, is_regex), summary)
    log.debug('attaching summary %s to "%s", is_regex=%s -> %s',
              summary_fn.__name__, type_name, is_regex, ret)


def get_synth_summary(synth_class, valobj, dict):
    ''''
    get_summary' is annoyingly not a part of the standard LLDB synth provider API.
    This trick allows us to share data extraction logic between synth providers and their sibling summary providers.
    '''
    synth = synth_class(valobj.GetNonSyntheticValue(), dict)
    synth.update()
    summary = synth.get_summary()
    return to_lldb_str(summary)


def member(valobj, *chain):
    '''Performs chained GetChildMemberWithName lookups'''
    for name in chain:
        valobj = valobj.GetChildMemberWithName(name)
    return valobj


class Printer(object):
    '''Base class for Printers'''

    def __init__(self, valobj, dict={}):
        self.valobj = valobj
        self.initialize()

    def initialize(self):
        return None

    def update(self):
        return False

    def num_children(self):
        return 0

    def has_children(self):
        return False

    def get_child_at_index(self, index):
        return None

    def get_child_index(self, name):
        return None

    def get_summary(self):
        return None

    def member(self, *chain):
        '''Performs chained GetChildMemberWithName lookups'''
        return member(self.valobj, *chain)

    def template_params(self):
        '''Returns list of template params values (as strings)'''
        type_name = self.valobj.GetTypeName()
        params = []
        level = 0
        start = 0
        for i, c in enumerate(type_name):
            if c == '<':
                level += 1
                if level == 1:
                    start = i + 1
            elif c == '>':
                level -= 1
                if level == 0:
                    params.append(type_name[start:i].strip())
            elif c == ',' and level == 1:
                params.append(type_name[start:i].strip())
                start = i + 1
        return params

    def template_param_at(self, index):
        '''Returns template param value at index (as string)'''
        return self.template_params()[index]


class UtilsSlicePrinter(Printer):
    '''Printer for tint::Slice<T>'''

    def initialize(self):
        self.len = self.valobj.GetChildMemberWithName('len')
        self.cap = self.valobj.GetChildMemberWithName('cap')
        self.data = self.valobj.GetChildMemberWithName('data')
        self.elem_type = self.data.GetType().GetPointeeType()
        self.elem_size = self.elem_type.GetByteSize()

    def get_summary(self):
        return 'length={} capacity={}'.format(self.len.GetValueAsUnsigned(),
                                              self.cap.GetValueAsUnsigned())

    def num_children(self):
        # NOTE: VS Code on MacOS hangs if we try to expand something too large, so put an artificial limit
        # until we can figure out how to know if this is a valid instance.
        return min(self.len.GetValueAsUnsigned(), 256)

    def has_children(self):
        return True

    def get_child_at_index(self, index):
        try:
            if not 0 <= index < self.num_children():
                return None
            # TODO: return self.value_at(index)
            offset = index * self.elem_size
            return self.data.CreateChildAtOffset('[%s]' % index, offset,
                                                 self.elem_type)
        except Exception as e:
            log.error('%s', e)
            raise

    def value_at(self, index):
        '''Returns array value at index'''
        offset = index * self.elem_size
        return self.data.CreateChildAtOffset('[%s]' % index, offset,
                                             self.elem_type)


class UtilsVectorPrinter(Printer):
    '''Printer for tint::Vector<T, N>'''

    def initialize(self):
        self.slice = self.member('impl_', 'slice')
        self.slice_printer = UtilsSlicePrinter(self.slice)
        self.fixed_size = int(self.template_param_at(1))
        self.cap = self.slice_printer.member('cap')

    def get_summary(self):
        using_heap = self.cap.GetValueAsUnsigned() > self.fixed_size
        return 'heap={} {}'.format(using_heap,
                                   self.slice_printer.get_summary())

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

    def has_children(self):
        return self.slice_printer.has_children()

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

    def make_slice_printer(self):
        return UtilsSlicePrinter(self.slice)


class UtilsVectorRefPrinter(Printer):
    '''Printer for tint::VectorRef<T>'''

    def initialize(self):
        self.slice = self.member('slice_')
        self.slice_printer = UtilsSlicePrinter(self.slice)
        self.can_move = self.member('can_move_')

    def get_summary(self):
        return 'can_move={} {}'.format(self.can_move.GetValue(),
                                       self.slice_printer.get_summary())

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

    def has_children(self):
        return self.slice_printer.has_children()

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


class UtilsHashmapBasePrinter(Printer):
    '''Base Printer for HashmapBase-derived types'''

    def initialize(self):
        self.slice = UtilsVectorPrinter(
            self.member('slots_')).make_slice_printer()

        self.try_read_std_optional_func = self.try_read_std_optional

    def update(self):
        self.valid_slots = []
        for slot in range(0, self.slice.num_children()):
            v = self.slice.value_at(slot)
            if member(v, 'hash').GetValueAsUnsigned() != 0:
                self.valid_slots.append(slot)
        return False

    def get_summary(self):
        return 'length={}'.format(self.num_children())

    def num_children(self):
        return len(self.valid_slots)

    def has_children(self):
        return True

    def get_child_at_index(self, index):
        slot = self.valid_slots[index]
        v = self.slice.value_at(slot)
        entry = member(v, 'entry')

        # entry is a std::optional, let's try to extract its value for display
        kvp = self.try_read_std_optional_func(slot, entry)
        if kvp is None:
            # If we failed, just output the slot and entry as is, which will use
            # the default printer for std::optional.
            kvp = slot, entry

        return kvp[1].CreateChildAtOffset('[{}]'.format(kvp[0]), 0,
                                          kvp[1].GetType())

    def try_read_std_optional(self, slot, entry):
        return None


class UtilsHashsetPrinter(UtilsHashmapBasePrinter):
    '''Printer for Hashset<T, N, HASH, EQUAL>'''

    def try_read_std_optional(self, slot, entry):
        try:
            # libc++
            v = entry.EvaluateExpression('__val_')
            if v.name is not None:
                return slot, v

            # libstdc++
            v = entry.EvaluateExpression('_M_payload._M_payload._M_value')
            if v.name is not None:
                return slot, v
            return None
        except:
            return None


class UtilsHashmapPrinter(UtilsHashsetPrinter):
    '''Printer for Hashmap<K, V, N, HASH, EQUAL>'''

    def try_read_std_optional(self, slot, entry):
        try:
            # libc++
            val = entry.EvaluateExpression('__val_')
            k = val.EvaluateExpression('key')
            v = val.EvaluateExpression('value')
            if k.name is not None and v.name is not None:
                return k.GetValue(), v

            # libstdc++
            val = entry.EvaluateExpression('_M_payload._M_payload._M_value')
            k = val.EvaluateExpression('key')
            v = val.EvaluateExpression('value')
            if k.name is not None and v.name is not None:
                return k.GetValue(), v
            return None
        except:
            return None
