/* Python interface to inferior stop events.

   Copyright (C) 2009-2024 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-stopevent.h"
#include "py-uiout.h"
#include "thread-fsm.h"

gdbpy_ref<>
create_stop_event_object (PyTypeObject *py_type, const gdbpy_ref<> &dict)
{
  gdbpy_ref<> thread = py_get_event_thread (inferior_ptid);
  if (thread == nullptr)
    return nullptr;

  gdbpy_ref<> result = create_thread_event_object (py_type, thread.get ());
  if (result == nullptr)
    return nullptr;

  if (evpy_add_attribute (result.get (), "details", dict.get ()) < 0)
    return nullptr;

  return result;
}

/* Print BPSTAT to a new Python dictionary.  Returns the dictionary,
   or null if a Python exception occurred.  */

static gdbpy_ref<>
py_print_bpstat (bpstat *bs, enum gdb_signal stop_signal)
{
  py_ui_out uiout;
  struct value *return_value = nullptr;

  try
    {
      scoped_restore save_uiout = make_scoped_restore (&current_uiout, &uiout);

      thread_info *tp = inferior_thread ();
      if (tp->thread_fsm () != nullptr && tp->thread_fsm ()->finished_p ())
	{
	  async_reply_reason reason = tp->thread_fsm ()->async_reply_reason ();
	  uiout.field_string ("reason", async_reason_lookup (reason));

	  return_value_info *rvinfo = tp->thread_fsm ()->return_value ();
	  if (rvinfo != nullptr && rvinfo->value != nullptr)
	    return_value = rvinfo->value;
	}

      if (stop_signal != GDB_SIGNAL_0 && stop_signal != GDB_SIGNAL_TRAP)
	print_signal_received_reason (&uiout, stop_signal);
      else
	{
	  struct target_waitstatus last;
	  get_last_target_status (nullptr, nullptr, &last);

	  bpstat_print (bs, last.kind ());
	}
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  gdbpy_ref<> dict = uiout.result ();
  if (dict == nullptr)
    return nullptr;

  /* This has to be done separately to avoid error issues, and because
     there's no API to add generic Python objects to a py_ui_out.  */
  if (return_value != nullptr)
    {
      gdbpy_ref<> val (value_to_value_object (return_value));
      if (val == nullptr)
	return nullptr;
      if (PyDict_SetItemString (dict.get (), "finish-value", val.get ()) < 0)
	return nullptr;
    }

  return dict;
}

/* Callback observers when a stop event occurs.  This function will create a
   new Python stop event object.  If only a specific thread is stopped the
   thread object of the event will be set to that thread.  Otherwise, if all
   threads are stopped thread object will be set to None.
   return 0 if the event was created and emitted successfully otherwise
   returns -1.  */

int
emit_stop_event (struct bpstat *bs, enum gdb_signal stop_signal)
{
  gdbpy_ref<> stop_event_obj;
  gdbpy_ref<> list;
  PyObject *first_bp = NULL;
  struct bpstat *current_bs;

  if (evregpy_no_listeners_p (gdb_py_events.stop))
    return 0;

  gdbpy_ref<> dict = py_print_bpstat (bs, stop_signal);
  if (dict == nullptr)
    return -1;

  /* Add any breakpoint set at this location to the list.  */
  for (current_bs = bs; current_bs != NULL; current_bs = current_bs->next)
    {
      if (current_bs->breakpoint_at
	  && current_bs->breakpoint_at->py_bp_object)
	{
	  PyObject *current_py_bp =
	      (PyObject *) current_bs->breakpoint_at->py_bp_object;

	  if (list == NULL)
	    {
	      list.reset (PyList_New (0));
	      if (list == NULL)
		return -1;
	    }

	  if (PyList_Append (list.get (), current_py_bp))
	    return -1;

	  if (first_bp == NULL)
	    first_bp = current_py_bp;
	}
    }

  if (list != NULL)
    {
      stop_event_obj = create_breakpoint_event_object (dict,
						       list.get (),
						       first_bp);
      if (stop_event_obj == NULL)
	return -1;
    }

  /* Check if the signal is "Signal 0" or "Trace/breakpoint trap".  */
  if (stop_signal != GDB_SIGNAL_0
      && stop_signal != GDB_SIGNAL_TRAP)
    {
      stop_event_obj = create_signal_event_object (dict, stop_signal);
      if (stop_event_obj == NULL)
	return -1;
    }

  /* If all fails emit an unknown stop event.  All event types should
     be known and this should eventually be unused.  */
  if (stop_event_obj == NULL)
    {
      stop_event_obj = create_stop_event_object (&stop_event_object_type,
						 dict);
      if (stop_event_obj == NULL)
	return -1;
    }

  return evpy_emit_event (stop_event_obj.get (), gdb_py_events.stop);
}
