/* Python interface to inferior events.

   Copyright (C) 2009-2026 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 "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 nullptr;

  if (!event_obj->allocate_dict ())
    return nullptr;

  return event_obj;
}

/* 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.  */

static int
gdbpy_initialize_event ()
{
  return gdbpy_type_ready (&event_object_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;
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_event);

static gdb_PyGetSetDef event_object_getset[] =
{
  gdbpy_dict_wrapper_cfg_dict_getter ("event"),
  { 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 */
  gdbpy_dict_wrapper_getsetattro,
  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 */
  0,                                          /* tp_dictoffset */
  0,                                          /* tp_init */
  0                                           /* tp_alloc */
};
