/* Convenience functions implemented in Python.

   Copyright (C) 2008-2023 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 "value.h"
#include "python-internal.h"
#include "charset.h"
#include "gdbcmd.h"
#include "cli/cli-decode.h"
#include "completer.h"
#include "expression.h"
#include "language.h"

extern PyTypeObject
  fnpy_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("PyObject");

/* Return a reference to a tuple ARGC elements long.  Each element of the
   tuple is a PyObject converted from the corresponding element of ARGV.  */

static gdbpy_ref<>
convert_values_to_python (int argc, struct value **argv)
{
  int i;
  gdbpy_ref<> result (PyTuple_New (argc));

  if (result == NULL)
    return NULL;

  for (i = 0; i < argc; ++i)
    {
      gdbpy_ref<> elt (value_to_value_object (argv[i]));
      if (elt == NULL)
	return NULL;
      PyTuple_SetItem (result.get (), i, elt.release ());
    }
  return result;
}

/* Call a Python function object's invoke method.  */

static struct value *
fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
	   void *cookie, int argc, struct value **argv)
{
  /* The gdbpy_enter object needs to be placed first, so that it's the last to
     be destroyed.  */
  gdbpy_enter enter_py (gdbarch, language);
  struct value *value;
  gdbpy_ref<> result;
  gdbpy_ref<> args = convert_values_to_python (argc, argv);

  /* convert_values_to_python can return NULL on error.  If we
     encounter this, do not call the function, but allow the Python ->
     error code conversion below to deal with the Python exception.
     Note, that this is different if the function simply does not
     have arguments.  */

  if (args != NULL)
    {
      gdbpy_ref<> callable (PyObject_GetAttrString ((PyObject *) cookie,
						    "invoke"));
      if (callable == NULL)
	error (_ ("No method named 'invoke' in object."));

      result.reset (PyObject_Call (callable.get (), args.get (), NULL));
    }

  if (result == NULL)
    gdbpy_handle_exception ();

  value = convert_value_from_python (result.get ());
  if (value == NULL)
    {
      gdbpy_print_stack ();
      error (_ ("Error while executing Python code."));
    }

  return value;
}

/* Initializer for a Function object.  It takes one argument, the name
   of the function.  */

static int
fnpy_init (PyObject *self, PyObject *args, PyObject *kwds)
{
  const char *name;
  gdb::unique_xmalloc_ptr<char> docstring;

  if (!PyArg_ParseTuple (args, "s", &name))
    return -1;

  gdbpy_ref<> self_ref = gdbpy_ref<>::new_reference (self);

  if (PyObject_HasAttrString (self, "__doc__"))
    {
      gdbpy_ref<> ds_obj (PyObject_GetAttrString (self, "__doc__"));
      if (ds_obj != NULL)
	{
	  if (gdbpy_is_string (ds_obj.get ()))
	    {
	      docstring = python_string_to_host_string (ds_obj.get ());
	      if (docstring == NULL)
		return -1;
	    }
	}
    }
  if (!docstring)
    docstring.reset (xstrdup (_ ("This function is not documented.")));

  add_internal_function (make_unique_xstrdup (name), std::move (docstring),
			 fnpy_call, self_ref.release ());
  return 0;
}

/* Initialize internal function support.  */

int
gdbpy_initialize_functions (void)
{
  fnpy_object_type.tp_new = PyType_GenericNew;
  if (PyType_Ready (&fnpy_object_type) < 0)
    return -1;

  return gdb_pymodule_addobject (gdb_module, "Function",
				 (PyObject *) &fnpy_object_type);
}

PyTypeObject fnpy_object_type = {
  PyVarObject_HEAD_INIT (NULL, 0) "gdb.Function", /*tp_name*/
  sizeof (PyObject),				  /*tp_basicsize*/
  0,						  /*tp_itemsize*/
  0,						  /*tp_dealloc*/
  0,						  /*tp_print*/
  0,						  /*tp_getattr*/
  0,						  /*tp_setattr*/
  0,						  /*tp_compare*/
  0,						  /*tp_repr*/
  0,						  /*tp_as_number*/
  0,						  /*tp_as_sequence*/
  0,						  /*tp_as_mapping*/
  0,						  /*tp_hash */
  0,						  /*tp_call*/
  0,						  /*tp_str*/
  0,						  /*tp_getattro*/
  0,						  /*tp_setattro*/
  0,						  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	  /*tp_flags*/
  "GDB function object",			  /* tp_doc */
  0,						  /* tp_traverse */
  0,						  /* tp_clear */
  0,						  /* tp_richcompare */
  0,						  /* tp_weaklistoffset */
  0,						  /* tp_iter */
  0,						  /* tp_iternext */
  0,						  /* tp_methods */
  0,						  /* tp_members */
  0,						  /* tp_getset */
  0,						  /* tp_base */
  0,						  /* tp_dict */
  0,						  /* tp_descr_get */
  0,						  /* tp_descr_set */
  0,						  /* tp_dictoffset */
  fnpy_init,					  /* tp_init */
  0,						  /* tp_alloc */
};
