# Copyright 2022 The Tint Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# 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::utils::Slice<.+>$', True)

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

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

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

    attach_synthetic_to_type(
        UtilsHashmapPrinter, r'^tint::utils::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::utils::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::utils::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::utils::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 UtilsHashsetPrinter(Printer):
    '''Printer for Hashset<T, N, HASH, EQUAL>'''

    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)
        value = member(v, 'value')

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

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

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

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


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

    def initialize(self):
        self.hash_set = UtilsHashsetPrinter(self.member('set_'))
        # Replace the lookup function so we can extract the key and value out of the std::optionals in the Hashset
        self.hash_set.try_read_std_optional_func = self.try_read_std_optional

    def update(self):
        self.hash_set.update()

    def get_summary(self):
        return self.hash_set.get_summary()

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

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

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

    def try_read_std_optional(self, slot, value):
        try:
            # libc++
            val = value.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 = value.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
        except:
            pass
        # Failed, fall back on hash_set
        return self.hash_set.try_read_std_optional(slot, value)
