# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""GDB support for Chrome types.

Add this to your gdb by amending your ~/.gdbinit as follows:
  python
  import sys
  sys.path.insert(0, "/path/to/tools/gdb/")
  import gdb_chrome
  end

Use
  (gdb) p /r any_variable
to print |any_variable| without using any printers.

To interactively type Python for development of the printers:
  (gdb) python foo = gdb.parse_and_eval('bar')
to put the C++ value 'bar' in the current scope into a Python variable 'foo'.
Then you can interact with that variable:
  (gdb) python print foo['impl_']
"""

import datetime
import gdb
import gdb.printing
import os
import sys

sys.path.insert(0, os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    'util'))
import class_methods

sys.path.insert(0, os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    '..', '..', 'third_party', 'blink', 'tools', 'gdb'))
try:
  import blink
finally:
  sys.path.pop(0)

# When debugging this module, set the below variable to True, and then use
#   (gdb) python del sys.modules['gdb_chrome']
#   (gdb) python import gdb_chrome
# to reload.
_DEBUGGING = False


pp_set = gdb.printing.RegexpCollectionPrettyPrinter("chromium")


def typed_ptr(ptr):
    """Prints a pointer along with its exact type.

    By default, gdb would print just the address, which takes more
    steps to interpret.
    """
    # Returning this as a cast expression surrounded by parentheses
    # makes it easier to cut+paste inside of gdb.
    return '((%s)%s)' % (ptr.dynamic_type, ptr)


def yield_fields(val):
    """Use this in a printer's children() method to print an object's fields.

    e.g.
      def children():
        for result in yield_fields(self.val):
          yield result
    """
    try:
        fields = val.type.target().fields()
    except:
        fields = val.type.fields()
    for field in fields:
        if field.is_base_class:
            yield (field.name, val.cast(gdb.lookup_type(field.name)))
        else:
            yield (field.name, val[field.name])


class Printer(object):
    def __init__(self, val):
        self.val = val


class StringPrinter(Printer):
    def display_hint(self):
        return 'string'


class String16Printer(StringPrinter):
    def to_string(self):
        return blink.ustring_to_string(self.val['_M_dataplus']['_M_p'])
pp_set.add_printer(
    'string16',
    '^string16|std::basic_string<(unsigned short|base::char16).*>$',
    String16Printer);


class GURLPrinter(StringPrinter):
    def to_string(self):
        return self.val['spec_']
pp_set.add_printer('GURL', '^GURL$', GURLPrinter)


class FilePathPrinter(StringPrinter):
    def to_string(self):
        return self.val['path_']['_M_dataplus']['_M_p']
pp_set.add_printer('FilePath', '^FilePath$', FilePathPrinter)


class SmartPtrPrinter(Printer):
    def to_string(self):
        return '%s%s' % (self.typename, typed_ptr(self.ptr()))


class ScopedPtrPrinter(SmartPtrPrinter):
    typename = 'scoped_ptr'
    def ptr(self):
        return self.val['impl_']['data_']['ptr']
pp_set.add_printer('scoped_ptr', '^scoped_ptr<.*>$', ScopedPtrPrinter)


class ScopedRefPtrPrinter(SmartPtrPrinter):
    typename = 'scoped_refptr'
    def ptr(self):
        return self.val['ptr_']
pp_set.add_printer('scoped_refptr', '^scoped_refptr<.*>$', ScopedRefPtrPrinter)


class LinkedPtrPrinter(SmartPtrPrinter):
    typename = 'linked_ptr'
    def ptr(self):
        return self.val['value_']
pp_set.add_printer('linked_ptr', '^linked_ptr<.*>$', LinkedPtrPrinter)


class WeakPtrPrinter(SmartPtrPrinter):
    typename = 'base::WeakPtr'
    def ptr(self):
        flag = ScopedRefPtrPrinter(self.val['ref_']['flag_']).ptr()
        if flag and flag['is_valid_']:
            return self.val['ptr_']
        return gdb.Value(0).cast(self.val['ptr_'].type)
pp_set.add_printer('base::WeakPtr', '^base::WeakPtr<.*>$', WeakPtrPrinter)


class CallbackPrinter(Printer):
    """Callbacks provide no usable information so reduce the space they take."""
    def to_string(self):
        return '...'
pp_set.add_printer('base::Callback', '^base::Callback<.*>$', CallbackPrinter)


class LocationPrinter(Printer):
    def to_string(self):
        return '%s()@%s:%s' % (self.val['function_name_'].string(),
                               self.val['file_name_'].string(),
                               self.val['line_number_'])
pp_set.add_printer('base::Location', '^base::Location$',
                   LocationPrinter)


class PendingTaskPrinter(Printer):
    def to_string(self):
        return 'From %s' % (self.val['posted_from'],)

    def children(self):
        for result in yield_fields(self.val):
            if result[0] not in ('task', 'posted_from'):
                yield result
pp_set.add_printer('base::PendingTask', '^base::PendingTask$',
                   PendingTaskPrinter)


class LockPrinter(Printer):
    def to_string(self):
        try:
            if self.val['owned_by_thread_']:
                return 'Locked by thread %s' % self.val['owning_thread_id_']
            else:
                return 'Unlocked'
        except gdb.error:
            return 'Unknown state'
pp_set.add_printer('base::Lock', '^base::Lock$', LockPrinter)


class TimeDeltaPrinter(object):
    def __init__(self, val):
        self._timedelta = datetime.timedelta(microseconds=int(val['delta_']))

    def timedelta(self):
        return self._timedelta

    def to_string(self):
        return str(self._timedelta)
pp_set.add_printer('base::TimeDelta', '^base::TimeDelta$', TimeDeltaPrinter)


class TimeTicksPrinter(TimeDeltaPrinter):
    def __init__(self, val):
        self._timedelta = datetime.timedelta(microseconds=int(val['us_']))
pp_set.add_printer('base::TimeTicks', '^base::TimeTicks$', TimeTicksPrinter)


class TimePrinter(object):
    def __init__(self, val):
        timet_offset = gdb.parse_and_eval(
            'base::Time::kTimeTToMicrosecondsOffset')
        self._datetime = (datetime.datetime.fromtimestamp(0) +
                          datetime.timedelta(microseconds=
                                             int(val['us_'] - timet_offset)))

    def datetime(self):
        return self._datetime

    def to_string(self):
        return str(self._datetime)
pp_set.add_printer('base::Time', '^base::Time$', TimePrinter)


class FlatTreePrinter(object):
    def __init__(self, val):
        self.val = val

    def to_string(self):
        # It would be nice to match the output of std::map which is a little
        # nicer than printing the vector of pairs. But iterating over it in
        # Python is much more complicated and this output is reasonable.
        # (Without this printer, a flat_map will output 7 lines of internal
        # template goop before the vector contents.)
        return 'base::flat_tree with ' + str(self.val['impl_']['body_'])
pp_set.add_printer('base::flat_map', '^base::flat_map<.*>$', FlatTreePrinter)
pp_set.add_printer('base::flat_set', '^base::flat_set<.*>$', FlatTreePrinter)
pp_set.add_printer('base::flat_tree', '^base::internal::flat_tree<.*>$',
                   FlatTreePrinter)


class ValuePrinter(object):
    def __init__(self, val):
        self.val = val

    def get_type(self):
        return self.val['type_']

    def to_string(self):
        typestr = str(self.get_type())
        # Trim prefix to just get the emum short name.
        typestr = typestr[typestr.rfind(':') + 1: ]

        if typestr == 'NONE':
            return 'base::Value of type NONE'
        if typestr == 'BOOLEAN':
            valuestr = self.val['bool_value_']
        if typestr == 'INTEGER':
            valuestr = self.val['int_value_']
        if typestr == 'DOUBLE':
            valuestr = self.val['double_value_']
        if typestr == 'STRING':
            valuestr = self.val['string_value_']
        if typestr == 'BINARY':
            valuestr = self.val['binary_value_']
        if typestr == 'DICTIONARY':
            valuestr = self.val['dict_']
        if typestr == 'LIST':
            valuestr = self.val['list_']

        return "base::Value of type %s = %s" % (typestr, str(valuestr))
pp_set.add_printer('base::Value', '^base::Value$', ValuePrinter)
pp_set.add_printer('base::ListValue', '^base::ListValue$', ValuePrinter)
pp_set.add_printer('base::DictionaryValue', '^base::DictionaryValue$',
                   ValuePrinter)


class IpcMessagePrinter(Printer):
    def header(self):
        return self.val['header_'].cast(
            gdb.lookup_type('IPC::Message::Header').pointer())

    def to_string(self):
        message_type = self.header()['type']
        return '%s of kind %s line %s' % (
            self.val.dynamic_type,
            (message_type >> 16).cast(gdb.lookup_type('IPCMessageStart')),
            message_type & 0xffff)

    def children(self):
        yield ('header_', self.header().dereference())
        yield ('capacity_after_header_', self.val['capacity_after_header_'])
        for field in self.val.type.fields():
            if field.is_base_class:
                continue
            yield (field.name, self.val[field.name])
pp_set.add_printer('IPC::Message', '^IPC::Message$', IpcMessagePrinter)


class NotificationRegistrarPrinter(Printer):
    def to_string(self):
        try:
            registrations = self.val['registered_']
            vector_finish = registrations['_M_impl']['_M_finish']
            vector_start = registrations['_M_impl']['_M_start']
            if vector_start == vector_finish:
                return 'Not watching notifications'
            if vector_start.dereference().type.sizeof == 0:
                # Incomplete type: b/8242773
                return 'Watching some notifications'
            return ('Watching %s notifications; '
                    'print %s->registered_ for details') % (
                        int(vector_finish - vector_start),
                        typed_ptr(self.val.address))
        except gdb.error:
            return 'NotificationRegistrar'
pp_set.add_printer('content::NotificationRegistrar',
                   '^content::NotificationRegistrar$',
                   NotificationRegistrarPrinter)


class SiteInstanceImplPrinter(object):
    def __init__(self, val):
        self.val = val.cast(val.dynamic_type)

    def to_string(self):
        return 'SiteInstanceImpl@%s for %s' % (
            self.val.address, self.val['site_'])

    def children(self):
        yield ('id_', self.val['id_'])
        yield ('has_site_', self.val['has_site_'])
        if self.val['browsing_instance_']['ptr_']:
            yield ('browsing_instance_', self.val['browsing_instance_']['ptr_'])
        if self.val['process_']:
            yield ('process_', typed_ptr(self.val['process_']))
pp_set.add_printer('content::SiteInstanceImpl', '^content::SiteInstanceImpl$',
                   SiteInstanceImplPrinter)


class RenderProcessHostImplPrinter(object):
    def __init__(self, val):
        self.val = val.cast(val.dynamic_type)

    def to_string(self):
        pid = ''
        try:
            child_process_launcher_ptr = (
                self.val['child_process_launcher_']['impl_']['data_']['ptr'])
            if child_process_launcher_ptr:
                context = (child_process_launcher_ptr['context_']['ptr_'])
                if context:
                    pid = ' PID %s' % str(context['process_']['process_'])
        except gdb.error:
            # The definition of the Context type may not be available.
            # b/8242773
            pass
        return 'RenderProcessHostImpl@%s%s' % (self.val.address, pid)

    def children(self):
        yield ('id_', self.val['id_'])
        yield ('listeners_',
               self.val['listeners_']['data_'])
        yield ('worker_ref_count_', self.val['worker_ref_count_'])
        yield ('fast_shutdown_started_', self.val['fast_shutdown_started_'])
        yield ('deleting_soon_', self.val['deleting_soon_'])
        yield ('pending_views_', self.val['pending_views_'])
        yield ('visible_widgets_', self.val['visible_widgets_'])
        yield ('backgrounded_', self.val['backgrounded_'])
        yield ('widget_helper_', self.val['widget_helper_'])
        yield ('is_initialized_', self.val['is_initialized_'])
        yield ('browser_context_', typed_ptr(self.val['browser_context_']))
        yield ('sudden_termination_allowed_',
               self.val['sudden_termination_allowed_'])
        yield ('ignore_input_events_', self.val['ignore_input_events_'])
        yield ('is_guest_', self.val['is_guest_'])
pp_set.add_printer('content::RenderProcessHostImpl',
                   '^content::RenderProcessHostImpl$',
                   RenderProcessHostImplPrinter)


gdb.printing.register_pretty_printer(gdb, pp_set, replace=_DEBUGGING)


"""Implementations of inlined libc++ std container functions."""
@class_methods.Class('std::__1::vector', template_types=['T'])
class LibcppVector(object):
    @class_methods.member_function('T&', 'operator[]', ['int'])
    def element(obj, i):
        return obj['__begin_'][i]

    @class_methods.member_function('size_t', 'size', [])
    def size(obj):
        return obj['__end_'] - obj['__begin_']

@class_methods.Class('std::__1::unique_ptr', template_types=['T'])
class LibcppUniquePtr(object):
    @class_methods.member_function('T*', 'get', [])
    def get(obj):
        return obj['__ptr_']['__value_']

    @class_methods.member_function('T*', 'operator->', [])
    def arrow(obj):
        return obj['__ptr_']['__value_']

    @class_methods.member_function('T&', 'operator*', [])
    def dereference(obj):
        return obj['__ptr_']['__value_'].dereference()
