/* Support for debug methods in Python.

   Copyright (C) 2013-2015 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "extension-priv.h"
#include "objfiles.h"
#include "value.h"
#include "language.h"

#include "python.h"
#include "python-internal.h"

static const char enabled_field_name[] = "enabled";
static const char match_method_name[] = "match";
static const char get_arg_types_method_name[] = "get_arg_types";
static const char get_result_type_method_name[] = "get_result_type";
static const char invoke_method_name[] = "invoke";
static const char matchers_attr_str[] = "xmethods";

static PyObject *py_match_method_name = NULL;
static PyObject *py_get_arg_types_method_name = NULL;
static PyObject *py_get_result_type_method_name = NULL;
static PyObject *py_invoke_method_name = NULL;

struct gdbpy_worker_data
{
  PyObject *worker;
  PyObject *this_type;
};

static struct xmethod_worker *new_python_xmethod_worker (PyObject *item,
							 PyObject *py_obj_type);

/* Implementation of free_xmethod_worker_data for Python.  */

void
gdbpy_free_xmethod_worker_data (const struct extension_language_defn *extlang,
				void *data)
{
  struct gdbpy_worker_data *worker_data = data;
  struct cleanup *cleanups;

  gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);

  /* We don't do much here, but we still need the GIL.  */
  cleanups = ensure_python_env (get_current_arch (), current_language);

  Py_DECREF (worker_data->worker);
  Py_DECREF (worker_data->this_type);
  xfree (worker_data);

  do_cleanups (cleanups);
}

/* Implementation of clone_xmethod_worker_data for Python.  */

void *
gdbpy_clone_xmethod_worker_data (const struct extension_language_defn *extlang,
				 void *data)
{
  struct gdbpy_worker_data *worker_data = data, *new_data;
  struct cleanup *cleanups;

  gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);

  /* We don't do much here, but we still need the GIL.  */
  cleanups = ensure_python_env (get_current_arch (), current_language);

  new_data = XCNEW (struct gdbpy_worker_data);
  new_data->worker = worker_data->worker;
  new_data->this_type = worker_data->this_type;
  Py_INCREF (new_data->worker);
  Py_INCREF (new_data->this_type);

  do_cleanups (cleanups);

  return new_data;
}

/* Invoke the "match" method of the MATCHER and return a new reference
   to the result.  Returns NULL on error.  */

static PyObject *
invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
		     const char *xmethod_name)
{
  PyObject *py_xmethod_name;
  PyObject *match_method, *enabled_field, *match_result;
  struct cleanup *cleanups;
  int enabled;

  cleanups = make_cleanup (null_cleanup, NULL);

  enabled_field = PyObject_GetAttrString (matcher, enabled_field_name);
  if (enabled_field == NULL)
    {
      do_cleanups (cleanups);
      return NULL;
    }
  make_cleanup_py_decref (enabled_field);

  enabled = PyObject_IsTrue (enabled_field);
  if (enabled == -1)
    {
      do_cleanups (cleanups);
      return NULL;
    }
  if (enabled == 0)
    {
      /* Return 'None' if the matcher is not enabled.  */
      do_cleanups (cleanups);
      Py_RETURN_NONE;
    }

  match_method = PyObject_GetAttrString (matcher, match_method_name);
  if (match_method == NULL)
    {
      do_cleanups (cleanups);
      return NULL;
    }
  make_cleanup_py_decref (match_method);

  py_xmethod_name = PyString_FromString (xmethod_name);
  if (py_xmethod_name == NULL)
    {
      do_cleanups (cleanups);
      return NULL;
    }
  make_cleanup_py_decref (py_xmethod_name);

  match_result = PyObject_CallMethodObjArgs (matcher,
					     py_match_method_name,
					     py_obj_type,
					     py_xmethod_name,
					     NULL);

  do_cleanups (cleanups);

  return match_result;
}

/* Implementation of get_matching_xmethod_workers for Python.  */

enum ext_lang_rc
gdbpy_get_matching_xmethod_workers
  (const struct extension_language_defn *extlang,
   struct type *obj_type, const char *method_name,
   xmethod_worker_vec **dm_vec)
{
  struct cleanup *cleanups;
  struct objfile *objfile;
  VEC (xmethod_worker_ptr) *worker_vec = NULL;
  PyObject *py_type, *py_progspace;
  PyObject *py_xmethod_matcher_list = NULL, *list_iter, *matcher;

  gdb_assert (obj_type != NULL && method_name != NULL);

  cleanups = ensure_python_env (get_current_arch (), current_language);

  py_type = type_to_type_object (obj_type);
  if (py_type == NULL)
    {
      gdbpy_print_stack ();
      do_cleanups (cleanups);

      return EXT_LANG_RC_ERROR;
    }
  make_cleanup_py_decref (py_type);

  /* Create an empty list of debug methods.  */
  py_xmethod_matcher_list = PyList_New (0);
  if (py_xmethod_matcher_list == NULL)
    {
      gdbpy_print_stack ();
      do_cleanups (cleanups);

      return EXT_LANG_RC_ERROR;
    }

  /* Gather debug method matchers registered with the object files.
     This could be done differently by iterating over each objfile's matcher
     list individually, but there's no data yet to show it's needed.  */
  ALL_OBJFILES (objfile)
    {
      PyObject *py_objfile = objfile_to_objfile_object (objfile);
      PyObject *objfile_matchers, *temp = py_xmethod_matcher_list;

      if (py_objfile == NULL)
	{
	  gdbpy_print_stack ();
	  Py_DECREF (py_xmethod_matcher_list);
	  do_cleanups (cleanups);

	  return EXT_LANG_RC_ERROR;
	}

      objfile_matchers = objfpy_get_xmethods (py_objfile, NULL);
      py_xmethod_matcher_list = PySequence_Concat (temp, objfile_matchers);
      Py_DECREF (temp);
      Py_DECREF (objfile_matchers);
      if (py_xmethod_matcher_list == NULL)
	{
	  gdbpy_print_stack ();
	  do_cleanups (cleanups);

	  return EXT_LANG_RC_ERROR;
	}
    }

  /* Gather debug methods matchers registered with the current program
     space.  */
  py_progspace = pspace_to_pspace_object (current_program_space);
  if (py_progspace != NULL)
    {
      PyObject *temp = py_xmethod_matcher_list;
      PyObject *pspace_matchers = pspy_get_xmethods (py_progspace, NULL);

      py_xmethod_matcher_list = PySequence_Concat (temp, pspace_matchers);
      Py_DECREF (temp);
      Py_DECREF (pspace_matchers);
      if (py_xmethod_matcher_list == NULL)
	{
	  gdbpy_print_stack ();
	  do_cleanups (cleanups);

	  return EXT_LANG_RC_ERROR;
	}
    }
  else
    {
      gdbpy_print_stack ();
      Py_DECREF (py_xmethod_matcher_list);
      do_cleanups (cleanups);

      return EXT_LANG_RC_ERROR;
    }

  /* Gather debug method matchers registered globally.  */
  if (gdb_python_module != NULL
      && PyObject_HasAttrString (gdb_python_module, matchers_attr_str))
    {
      PyObject *gdb_matchers;
      PyObject *temp = py_xmethod_matcher_list;

      gdb_matchers = PyObject_GetAttrString (gdb_python_module,
					     matchers_attr_str);
      if (gdb_matchers != NULL)
	{
	  py_xmethod_matcher_list = PySequence_Concat (temp, gdb_matchers);
	  Py_DECREF (temp);
	  Py_DECREF (gdb_matchers);
	  if (py_xmethod_matcher_list == NULL)
	    {
	      gdbpy_print_stack ();
	      do_cleanups (cleanups);

	      return EXT_LANG_RC_ERROR;
	    }
	}
      else
	{
	  gdbpy_print_stack ();
	  Py_DECREF (py_xmethod_matcher_list);
	  do_cleanups (cleanups);

	  return EXT_LANG_RC_ERROR;
	}
    }

  /* Safe to make a cleanup for py_xmethod_matcher_list now as it
     will not change any more.  */
  make_cleanup_py_decref (py_xmethod_matcher_list);

  list_iter = PyObject_GetIter (py_xmethod_matcher_list);
  if (list_iter == NULL)
    {
      gdbpy_print_stack ();
      do_cleanups (cleanups);

      return EXT_LANG_RC_ERROR;
    }
  while ((matcher = PyIter_Next (list_iter)) != NULL)
    {
      PyObject *match_result = invoke_match_method (matcher, py_type,
						    method_name);

      if (match_result == NULL)
	{
	  gdbpy_print_stack ();
	  Py_DECREF (matcher);
	  do_cleanups (cleanups);

	  return EXT_LANG_RC_ERROR;
	}
      if (match_result == Py_None)
	; /* This means there was no match.  */
      else if (PySequence_Check (match_result))
	{
	  PyObject *iter = PyObject_GetIter (match_result);
	  PyObject *py_worker;

	  if (iter == NULL)
	    {
	      gdbpy_print_stack ();
	      Py_DECREF (matcher);
	      Py_DECREF (match_result);
	      do_cleanups (cleanups);

	      return EXT_LANG_RC_ERROR;
	    }
	  while ((py_worker = PyIter_Next (iter)) != NULL)
	    {
	      struct xmethod_worker *worker;

	      worker = new_python_xmethod_worker (py_worker, py_type);
	      VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
	      Py_DECREF (py_worker);
	    }
	  Py_DECREF (iter);
	  /* Report any error that could have occurred while iterating.  */
	  if (PyErr_Occurred ())
	    {
	      gdbpy_print_stack ();
	      Py_DECREF (matcher);
	      Py_DECREF (match_result);
	      do_cleanups (cleanups);

	      return EXT_LANG_RC_ERROR;
	    }
	}
      else
	{
	  struct xmethod_worker *worker;

	  worker = new_python_xmethod_worker (match_result, py_type);
	  VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
	}

      Py_DECREF (match_result);
      Py_DECREF (matcher);
    }
  Py_DECREF (list_iter);
  /* Report any error that could have occurred while iterating.  */
  if (PyErr_Occurred ())
    {
      gdbpy_print_stack ();
      do_cleanups (cleanups);

      return EXT_LANG_RC_ERROR;
    }

  do_cleanups (cleanups);
  *dm_vec = worker_vec;

  return EXT_LANG_RC_OK;
}

/* Implementation of get_xmethod_arg_types for Python.  */

enum ext_lang_rc
gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
			     struct xmethod_worker *worker,
			     int *nargs, struct type ***arg_types)
{
  struct gdbpy_worker_data *worker_data = worker->data;
  PyObject *py_worker = worker_data->worker;
  PyObject *get_arg_types_method;
  PyObject *py_argtype_list, *list_iter = NULL, *item;
  struct cleanup *cleanups;
  struct type **type_array, *obj_type;
  int i = 1, arg_count;

  /* Set nargs to -1 so that any premature return from this function returns
     an invalid/unusable number of arg types.  */
  *nargs = -1;

  cleanups = ensure_python_env (get_current_arch (), current_language);

  get_arg_types_method =  PyObject_GetAttrString (py_worker,
						  get_arg_types_method_name);
  if (get_arg_types_method == NULL)
    {
      gdbpy_print_stack ();
      do_cleanups (cleanups);

      return EXT_LANG_RC_ERROR;
    }
  make_cleanup_py_decref (get_arg_types_method);

  py_argtype_list = PyObject_CallMethodObjArgs (py_worker,
						py_get_arg_types_method_name,
						NULL);
  if (py_argtype_list == NULL)
    {
      gdbpy_print_stack ();
      do_cleanups (cleanups);

      return EXT_LANG_RC_ERROR;
    }
  make_cleanup_py_decref (py_argtype_list);
  if (py_argtype_list == Py_None)
    arg_count = 0;
  else if (PySequence_Check (py_argtype_list))
    {
      arg_count = PySequence_Size (py_argtype_list);
      if (arg_count == -1)
	{
	  gdbpy_print_stack ();
	  do_cleanups (cleanups);

	  return EXT_LANG_RC_ERROR;
	}

      list_iter = PyObject_GetIter (py_argtype_list);
      if (list_iter == NULL)
	{
	  gdbpy_print_stack ();
	  do_cleanups (cleanups);

	  return EXT_LANG_RC_ERROR;
	}
      make_cleanup_py_decref (list_iter);
    }
  else
    arg_count = 1;

  /* Include the 'this' argument in the size.  */
  type_array = XCNEWVEC (struct type *, arg_count + 1);
  i = 1;
  if (list_iter != NULL)
    {
      while ((item = PyIter_Next (list_iter)) != NULL)
	{
	  struct type *arg_type = type_object_to_type (item);

	  Py_DECREF (item);
	  if (arg_type == NULL)
	    {
	      PyErr_SetString (PyExc_TypeError,
			       _("Arg type returned by the get_arg_types "
				 "method of a debug method worker object is "
				 "not a gdb.Type object."));
	      break;
	    }

	  type_array[i] = arg_type;
	  i++;
	}
    }
  else if (arg_count == 1)
    {
      /* py_argtype_list is not actually a list but a single gdb.Type
	 object.  */
      struct type *arg_type = type_object_to_type (py_argtype_list);

      if (arg_type == NULL)
	{
	  PyErr_SetString (PyExc_TypeError,
			   _("Arg type returned by the get_arg_types method "
			     "of an xmethod worker object is not a gdb.Type "
			     "object."));
	}
      else
	{
	  type_array[i] = arg_type;
	  i++;
	}
    }
  if (PyErr_Occurred ())
    {
      gdbpy_print_stack ();
      do_cleanups (cleanups);
      xfree (type_array);

      return EXT_LANG_RC_ERROR;
    }

  /* Add the type of 'this' as the first argument.  The 'this' pointer should
     be a 'const' value.  Hence, create a 'const' variant of the 'this' pointer
     type.  */
  obj_type = type_object_to_type (worker_data->this_type);
  type_array[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type), NULL);
  *nargs = i;
  *arg_types = type_array;
  do_cleanups (cleanups);

  return EXT_LANG_RC_OK;
}

/* Implementation of get_xmethod_result_type for Python.  */

enum ext_lang_rc
gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
			       struct xmethod_worker *worker,
			       struct value *obj,
			       struct value **args, int nargs,
			       struct type **result_type_ptr)
{
  struct gdbpy_worker_data *worker_data = worker->data;
  PyObject *py_worker = worker_data->worker;
  PyObject *py_value_obj, *py_arg_tuple, *py_result_type;
  PyObject *get_result_type_method;
  struct type *obj_type, *this_type;
  struct cleanup *cleanups;
  int i;

  cleanups = ensure_python_env (get_current_arch (), current_language);

  /* First see if there is a get_result_type method.
     If not this could be an old xmethod (pre 7.9.1).  */
  get_result_type_method
    = PyObject_GetAttrString (py_worker, get_result_type_method_name);
  if (get_result_type_method == NULL)
    {
      PyErr_Clear ();
      do_cleanups (cleanups);
      *result_type_ptr = NULL;
      return EXT_LANG_RC_OK;
    }
  make_cleanup_py_decref (get_result_type_method);

  obj_type = check_typedef (value_type (obj));
  this_type = check_typedef (type_object_to_type (worker_data->this_type));
  if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
    {
      struct type *this_ptr = lookup_pointer_type (this_type);

      if (!types_equal (obj_type, this_ptr))
	obj = value_cast (this_ptr, obj);
    }
  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
    {
      struct type *this_ref = lookup_reference_type (this_type);

      if (!types_equal (obj_type, this_ref))
	obj = value_cast (this_ref, obj);
    }
  else
    {
      if (!types_equal (obj_type, this_type))
	obj = value_cast (this_type, obj);
    }
  py_value_obj = value_to_value_object (obj);
  if (py_value_obj == NULL)
    goto Fail;
  make_cleanup_py_decref (py_value_obj);

  py_arg_tuple = PyTuple_New (nargs + 1);
  if (py_arg_tuple == NULL)
    goto Fail;
  make_cleanup_py_decref (py_arg_tuple);

  /* PyTuple_SET_ITEM steals the reference of the element.  Hence INCREF the
     reference to the 'this' object as we have a cleanup to DECREF it.  */
  Py_INCREF (py_value_obj);
  PyTuple_SET_ITEM (py_arg_tuple, 0, py_value_obj);

  for (i = 0; i < nargs; i++)
    {
      PyObject *py_value_arg = value_to_value_object (args[i]);

      if (py_value_arg == NULL)
	goto Fail;
      PyTuple_SET_ITEM (py_arg_tuple, i + 1, py_value_arg);
    }

  py_result_type = PyObject_CallObject (get_result_type_method, py_arg_tuple);
  if (py_result_type == NULL)
    goto Fail;
  make_cleanup_py_decref (py_result_type);

  *result_type_ptr = type_object_to_type (py_result_type);
  if (*result_type_ptr == NULL)
    {
      PyErr_SetString (PyExc_TypeError,
		       _("Type returned by the get_result_type method of an"
			 " xmethod worker object is not a gdb.Type object."));
      goto Fail;
    }

  do_cleanups (cleanups);
  return EXT_LANG_RC_OK;

 Fail:
  gdbpy_print_stack ();
  do_cleanups (cleanups);
  return EXT_LANG_RC_ERROR;
}

/* Implementation of invoke_xmethod for Python.  */

struct value *
gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
		      struct xmethod_worker *worker,
		      struct value *obj, struct value **args, int nargs)
{
  int i;
  struct cleanup *cleanups;
  PyObject *py_value_obj, *py_arg_tuple, *py_result;
  struct type *obj_type, *this_type;
  struct value *res = NULL;
  struct gdbpy_worker_data *worker_data = worker->data;
  PyObject *xmethod_worker = worker_data->worker;

  cleanups = ensure_python_env (get_current_arch (), current_language);

  obj_type = check_typedef (value_type (obj));
  this_type = check_typedef (type_object_to_type (worker_data->this_type));
  if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
    {
      struct type *this_ptr = lookup_pointer_type (this_type);

      if (!types_equal (obj_type, this_ptr))
	obj = value_cast (this_ptr, obj);
    }
  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
    {
      struct type *this_ref = lookup_reference_type (this_type);

      if (!types_equal (obj_type, this_ref))
	obj = value_cast (this_ref, obj);
    }
  else
    {
      if (!types_equal (obj_type, this_type))
	obj = value_cast (this_type, obj);
    }
  py_value_obj = value_to_value_object (obj);
  if (py_value_obj == NULL)
    {
      gdbpy_print_stack ();
      error (_("Error while executing Python code."));
    }
  make_cleanup_py_decref (py_value_obj);

  py_arg_tuple = PyTuple_New (nargs + 1);
  if (py_arg_tuple == NULL)
    {
      gdbpy_print_stack ();
      error (_("Error while executing Python code."));
    }
  make_cleanup_py_decref (py_arg_tuple);

  /* PyTuple_SET_ITEM steals the reference of the element.  Hence INCREF the
     reference to the 'this' object as we have a cleanup to DECREF it.  */
  Py_INCREF (py_value_obj);
  PyTuple_SET_ITEM (py_arg_tuple, 0, py_value_obj);

  for (i = 0; i < nargs; i++)
    {
      PyObject *py_value_arg = value_to_value_object (args[i]);

      if (py_value_arg == NULL)
	{
	  gdbpy_print_stack ();
	  error (_("Error while executing Python code."));
	}

      PyTuple_SET_ITEM (py_arg_tuple, i + 1, py_value_arg);
    }

  py_result = PyObject_CallObject (xmethod_worker, py_arg_tuple);
  if (py_result == NULL)
    {
      gdbpy_print_stack ();
      error (_("Error while executing Python code."));
    }
  make_cleanup_py_decref (py_result);

  if (py_result != Py_None)
    {
      res = convert_value_from_python (py_result);
      if (res == NULL)
	{
	  gdbpy_print_stack ();
	  error (_("Error while executing Python code."));
	}
    }
  else
    {
      res = allocate_value (lookup_typename (python_language, python_gdbarch,
					     "void", NULL, 0));
    }

  do_cleanups (cleanups);

  return res;
}

/* Creates a new Python xmethod_worker object.
   The new object has data of type 'struct gdbpy_worker_data' composed
   with the components PY_WORKER and THIS_TYPE.  */

static struct xmethod_worker *
new_python_xmethod_worker (PyObject *py_worker, PyObject *this_type)
{
  struct gdbpy_worker_data *data;

  gdb_assert (py_worker != NULL && this_type != NULL);

  data = XCNEW (struct gdbpy_worker_data);
  data->worker = py_worker;
  data->this_type = this_type;
  Py_INCREF (py_worker);
  Py_INCREF (this_type);

  return new_xmethod_worker (&extension_language_python, data);
}

int
gdbpy_initialize_xmethods (void)
{
  py_match_method_name = PyString_FromString (match_method_name);
  if (py_match_method_name == NULL)
    return -1;

  py_invoke_method_name = PyString_FromString (invoke_method_name);
  if (py_invoke_method_name == NULL)
    return -1;

  py_get_arg_types_method_name
    = PyString_FromString (get_arg_types_method_name);
  if (py_get_arg_types_method_name == NULL)
    return -1;

  py_get_result_type_method_name
    = PyString_FromString (get_result_type_method_name);
  if (py_get_result_type_method_name == NULL)
    return -1;

  return 1;
}
