# Copyright (c) 2018 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.

"""Helper library for defining XMethod implementations on C++ classes.

Include this library and then define python implementations of C++ methods
using the Class and member_function decorator functions.
"""

import gdb
import gdb.xmethod
import operator
import re


class MemberFunction(object):
  def __init__(self, return_type, name, arguments, wrapped_function):
    self.return_type = return_type
    self.name = name
    self.arguments = arguments
    self.function_ = wrapped_function

  def __call__(self, *args):
    self.function_(*args)


def member_function(return_type, name, arguments):
  """Decorate a member function.

  See Class decorator for example usage within a class.

  Args:
    return_type: The return type of the function (e.g. 'int')
    name: The function name (e.g. 'sum')
    arguments: The argument types for this function (e.g. ['int', 'int'])

    Each type can be a string (e.g. 'int', 'std::string', 'T*') or a
    function which constructs the return type. See CreateTypeResolver
    for details about type resolution.
  """
  def DefineMember(fn):
    return MemberFunction(return_type, name, arguments, fn)
  return DefineMember


def Class(class_name, template_types):
  """Decorate a python class with its corresponding C++ type.
  Args:
    class_name: The canonical string identifier for the class (e.g. base::Foo)
    template_types: An array of names for each templated type (e.g. ['K',
    'V'])

  Example:
    As an example, the following is an implementation of size() and operator[]
    on std::__1::vector, functions which are normally inlined and not
    normally callable from gdb.

    @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_']

  Note:
    Note that functions are looked up by the function name, which means that
    functions cannot currently have overloaded implementations for different
    arguments.
  """

  class MethodWorkerWrapper(gdb.xmethod.XMethod):
    """Wrapper of an XMethodWorker class as an XMethod."""
    def __init__(self, name, worker_class):
      super(MethodWorkerWrapper, self).__init__(name)
      self.name = name
      self.worker_class = worker_class


  class ClassMatcher(gdb.xmethod.XMethodMatcher):
    """Matches member functions of one class template."""
    def __init__(self, obj):
      super(ClassMatcher, self).__init__(class_name)

      # Constructs a regular expression to match this type.
      self._class_regex = re.compile(
          '^' + re.escape(class_name) +
          ('<.*>' if len(template_types) > 0 else '') + '$')

      # Construct a dictionary and array of methods
      self.dict = {}
      self.methods = []
      for name in dir(obj):
        attr = getattr(obj, name)
        if not isinstance(attr, MemberFunction):
          continue

        name = attr.name
        return_type = CreateTypeResolver(attr.return_type)
        arguments = [CreateTypeResolver(arg) for arg in
                     attr.arguments]
        method = MethodWorkerWrapper(
            attr.name,
            CreateTemplatedMethodWorker(return_type,
                                        arguments, attr.function_))
        self.methods.append(method)

    def match(self, class_type, method_name):
      if not re.match(self._class_regex, class_type.tag):
        return None
      templates = [class_type.template_argument(i) for i in
                   range(len(template_types))]
      return [method.worker_class(templates) for method in self.methods
              if method.name == method_name and method.enabled]


  def CreateTypeResolver(type_desc):
    """Creates a callback which resolves to the appropriate type when
    invoked.

    This is a helper to allow specifying simple types as strings when
    writing function descriptions. For complex cases, a callback can be
    passed which will be invoked when template instantiation is known.

    Args:
      type_desc: A callback generating the type or a string description of
          the type to lookup. Supported types are classes in the
          template_classes array (e.g. T) which will be looked up when those
          templated classes are known, or globally visible type names (e.g.
          int, base::Foo).

          Types can be modified by appending a '*' or '&' to denote a
          pointer or reference.

          If a callback is used, the callback will be passed an array of the
          instantiated template types.

    Note:
      This does not parse complex types such as std::vector<T>::iterator,
      to refer to types like these you must currently write a callback
      which constructs the appropriate type.
    """
    if callable(type_desc):
      return type_desc
    if type_desc == 'void':
      return lambda T: None
    if type_desc[-1] == '&':
      inner_resolver = CreateTypeResolver(type_desc[:-1])
      return lambda template_types: inner_resolver(template_types).reference()
    if type_desc[-1] == '*':
      inner_resolver = CreateTypeResolver(type_desc[:-1])
      return lambda template_types: inner_resolver(template_types).pointer()
    try:
      template_index = template_types.index(type_desc)
      return operator.itemgetter(template_index)
    except ValueError:
      return lambda template_types: gdb.lookup_type(type_desc)


  def CreateTemplatedMethodWorker(return_callback, args_callbacks,
                                  method_callback):
    class TemplatedMethodWorker(gdb.xmethod.XMethodWorker):
      def __init__(self, templates):
        super(TemplatedMethodWorker, self).__init__()
        self._templates = templates

      def get_arg_types(self):
        return [cb(self._templates) for cb in args_callbacks]

      def get_result_type(self, obj):
        return return_callback(self._templates)

      def __call__(self, *args):
        return method_callback(*args)
    return TemplatedMethodWorker

  def DefineClass(obj):
    matcher = ClassMatcher(obj)
    gdb.xmethod.register_xmethod_matcher(None, matcher)
    return matcher

  return DefineClass
