/* Python interface to inferior events.

   Copyright (C) 2009-2021 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 "py-event.h"

void
evpy_dealloc (PyObject *self)
{
  Py_XDECREF (((event_object *) self)->dict);
  Py_TYPE (self)->tp_free (self);
}

gdbpy_ref<>
create_event_object (PyTypeObject *py_type)
{
  gdbpy_ref<event_object> event_obj (PyObject_New (event_object, py_type));
  if (event_obj == NULL)
    return NULL;

  event_obj->dict = PyDict_New ();
  if (!event_obj->dict)
    return NULL;

  return gdbpy_ref<> ((PyObject *) event_obj.release ());
}

/* Add the attribute ATTR to the event object EVENT.  In
   python this attribute will be accessible by the name NAME.
   returns 0 if the operation succeeds and -1 otherwise.  This
   function acquires a new reference to ATTR.  */

int
evpy_add_attribute (PyObject *event, const char *name, PyObject *attr)
{
  return PyObject_SetAttrString (event, name, attr);
}

/* Initialize the Python event code.  */

int
gdbpy_initialize_event (void)
{
  return gdbpy_initialize_event_generic (&event_object_type,
					 "Event");
}

/* Initialize the given event type.  If BASE is not NULL it will
  be set as the types base.
  Returns 0 if initialization was successful -1 otherwise.  */

int
gdbpy_initialize_event_generic (PyTypeObject *type,
				const char *name)
{
  if (PyType_Ready (type) < 0)
    return -1;

  return gdb_pymodule_addobject (gdb_module, name, (PyObject *) type);
}


/* Notify the list of listens that the given EVENT has occurred.
   returns 0 if emit is successful -1 otherwise.  */

int
evpy_emit_event (PyObject *event,
		 eventregistry_object *registry)
{
  Py_ssize_t i;

  /* Create a copy of call back list and use that for
     notifying listeners to avoid skipping callbacks
     in the case of a callback being disconnected during
     a notification.  */
  gdbpy_ref<> callback_list_copy (PySequence_List (registry->callbacks));
  if (callback_list_copy == NULL)
    return -1;

  for (i = 0; i < PyList_Size (callback_list_copy.get ()); i++)
    {
      PyObject *func = PyList_GetItem (callback_list_copy.get (), i);

      if (func == NULL)
	return -1;

      gdbpy_ref<> func_result (PyObject_CallFunctionObjArgs (func, event,
							     NULL));

      if (func_result == NULL)
	{
	  /* Print the trace here, but keep going -- we want to try to
	     call all of the callbacks even if one is broken.  */
	  gdbpy_print_stack ();
	}
    }

  return 0;
}

static gdb_PyGetSetDef event_object_getset[] =
{
  { "__dict__", gdb_py_generic_dict, NULL,
    "The __dict__ for this event.", &event_object_type },
  { NULL }
};

PyTypeObject event_object_type =
{
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.Event",                                /* tp_name */
  sizeof (event_object),                      /* tp_basicsize */
  0,                                          /* tp_itemsize */
  evpy_dealloc,                               /* 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 event 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 */
  event_object_getset,			      /* tp_getset */
  0,                                          /* tp_base */
  0,                                          /* tp_dict */
  0,                                          /* tp_descr_get */
  0,                                          /* tp_descr_set */
  offsetof (event_object, dict),              /* tp_dictoffset */
  0,                                          /* tp_init */
  0                                           /* tp_alloc */
};
