/* Python interface to inferior threads.

   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 "gdbthread.h"
#include "inferior.h"
#include "python-internal.h"

extern PyTypeObject thread_object_type;

/* Require that INFERIOR be a valid inferior ID.  */
#define THPY_REQUIRE_VALID(Thread)				\
  do {								\
    if (!Thread->thread)					\
      {								\
	PyErr_SetString (PyExc_RuntimeError,			\
			 _("Thread no longer exists."));	\
	return NULL;						\
      }								\
  } while (0)

gdbpy_ref<thread_object>
create_thread_object (struct thread_info *tp)
{
  gdbpy_ref<thread_object> thread_obj;

  gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
  if (inf_obj == NULL)
    return nullptr;

  thread_obj.reset (PyObject_New (thread_object, &thread_object_type));
  if (thread_obj == NULL)
    return nullptr;

  thread_obj->thread = tp;
  thread_obj->inf_obj = (PyObject *) inf_obj.release ();
  if (!thread_obj->allocate_dict ())
    return nullptr;

  return thread_obj;
}

static void
thpy_dealloc (PyObject *self)
{
  thread_object *thr_obj = (thread_object *) self;

  gdb_assert (thr_obj->inf_obj != nullptr);

  Py_DECREF (thr_obj->inf_obj);
  Py_XDECREF (thr_obj->dict);

  Py_TYPE (self)->tp_free (self);
}

static PyObject *
thpy_get_name (PyObject *self, void *ignore)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);

  const char *name = thread_name (thread_obj->thread);
  if (name == NULL)
    Py_RETURN_NONE;

  return PyUnicode_FromString (name);
}

/* Return a string containing target specific additional information about
   the state of the thread, or None, if there is no such additional
   information.  */

static PyObject *
thpy_get_details (PyObject *self, void *ignore)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);

  /* GCC can't tell that extra_info will always be assigned after the
     'catch', so initialize it.  */
  const char *extra_info = nullptr;
  try
    {
      extra_info = target_extra_thread_info (thread_obj->thread);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }
  if (extra_info == nullptr)
    Py_RETURN_NONE;

  return PyUnicode_FromString (extra_info);
}

static int
thpy_set_name (PyObject *self, PyObject *newvalue, void *ignore)
{
  thread_object *thread_obj = (thread_object *) self;
  gdb::unique_xmalloc_ptr<char> name;

  if (! thread_obj->thread)
    {
      PyErr_SetString (PyExc_RuntimeError, _("Thread no longer exists."));
      return -1;
    }

  if (newvalue == NULL)
    {
      PyErr_SetString (PyExc_TypeError,
		       _("Cannot delete `name' attribute."));
      return -1;
    }
  else if (newvalue == Py_None)
    {
      /* Nothing.  */
    }
  else if (! gdbpy_is_string (newvalue))
    {
      PyErr_SetString (PyExc_TypeError,
		       _("The value of `name' must be a string."));
      return -1;
    }
  else
    {
      name = python_string_to_host_string (newvalue);
      if (! name)
	return -1;
    }

  thread_obj->thread->set_name (std::move (name));

  return 0;
}

/* Getter for InferiorThread.num.  */

static PyObject *
thpy_get_num (PyObject *self, void *closure)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);

  gdbpy_ref<> result
    = gdb_py_object_from_longest (thread_obj->thread->per_inf_num);
  return result.release ();
}

/* Getter for InferiorThread.global_num.  */

static PyObject *
thpy_get_global_num (PyObject *self, void *closure)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);

  gdbpy_ref<> result
    = gdb_py_object_from_longest (thread_obj->thread->global_num);
  return result.release ();
}

/* Getter for InferiorThread.ptid  -> (pid, lwp, tid).
   Returns a tuple with the thread's ptid components.  */

static PyObject *
thpy_get_ptid (PyObject *self, void *closure)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);

  return gdbpy_create_ptid_object (thread_obj->thread->ptid).release ();
}

/* Implement gdb.InferiorThread.ptid_string attribute.  */

static PyObject *
thpy_get_ptid_string (PyObject *self, void *closure)
{
  thread_object *thread_obj = (thread_object *) self;
  THPY_REQUIRE_VALID (thread_obj);
  ptid_t ptid = thread_obj->thread->ptid;

  try
    {
      /* Select the correct inferior before calling a target_* function.  */
      scoped_restore_current_thread restore_thread;
      switch_to_inferior_no_thread (thread_obj->thread->inf);
      std::string ptid_str = target_pid_to_str (ptid);
      return PyUnicode_FromString (ptid_str.c_str ());
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }
}

/* Getter for InferiorThread.inferior -> Inferior.  */

static PyObject *
thpy_get_inferior (PyObject *self, void *ignore)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);
  Py_INCREF (thread_obj->inf_obj);

  return thread_obj->inf_obj;
}

/* Implementation of InferiorThread.switch ().
   Makes this the GDB selected thread.  */

static PyObject *
thpy_switch (PyObject *self, PyObject *args)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);

  try
    {
      switch_to_thread (thread_obj->thread);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  Py_RETURN_NONE;
}

/* Implementation of InferiorThread.is_stopped () -> Boolean.
   Return whether the thread is stopped.  */

static PyObject *
thpy_is_stopped (PyObject *self, PyObject *args)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);

  if (thread_obj->thread->state == THREAD_STOPPED)
    Py_RETURN_TRUE;

  Py_RETURN_FALSE;
}

/* Implementation of InferiorThread.is_running () -> Boolean.
   Return whether the thread is running.  */

static PyObject *
thpy_is_running (PyObject *self, PyObject *args)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);

  if (thread_obj->thread->state == THREAD_RUNNING)
    Py_RETURN_TRUE;

  Py_RETURN_FALSE;
}

/* Implementation of InferiorThread.is_exited () -> Boolean.
   Return whether the thread is exited.  */

static PyObject *
thpy_is_exited (PyObject *self, PyObject *args)
{
  thread_object *thread_obj = (thread_object *) self;

  THPY_REQUIRE_VALID (thread_obj);

  if (thread_obj->thread->state == THREAD_EXITED)
    Py_RETURN_TRUE;

  Py_RETURN_FALSE;
}

/* Implementation of gdb.InfThread.is_valid (self) -> Boolean.
   Returns True if this inferior Thread object still exists
   in GDB.  */

static PyObject *
thpy_is_valid (PyObject *self, PyObject *args)
{
  thread_object *thread_obj = (thread_object *) self;

  if (! thread_obj->thread)
    Py_RETURN_FALSE;

  Py_RETURN_TRUE;
}

/* Implementation of gdb.InferiorThread.handle (self) -> handle. */

static PyObject *
thpy_thread_handle (PyObject *self, PyObject *args)
{
  thread_object *thread_obj = (thread_object *) self;
  THPY_REQUIRE_VALID (thread_obj);

  gdb::array_view<const gdb_byte> hv;

  try
    {
      hv = target_thread_info_to_thread_handle (thread_obj->thread);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  if (hv.size () == 0)
    {
      PyErr_SetString (PyExc_RuntimeError, _("Thread handle not found."));
      return NULL;
    }

  PyObject *object = PyBytes_FromStringAndSize ((const char *) hv.data (),
						hv.size());
  return object;
}

/* Implement repr() for gdb.InferiorThread.  */

static PyObject *
thpy_repr (PyObject *self)
{
  thread_object *thread_obj = (thread_object *) self;

  if (thread_obj->thread == nullptr)
    return gdb_py_invalid_object_repr (self);

  thread_info *thr = thread_obj->thread;
  return PyUnicode_FromFormat ("<%s id=%s target-id=\"%s\">",
			       Py_TYPE (self)->tp_name,
			       print_full_thread_id (thr),
			       target_pid_to_str (thr->ptid).c_str ());
}

/* See python-internal.h.  */

gdbpy_ref<>
gdbpy_create_ptid_object (ptid_t ptid)
{
  int pid = ptid.pid ();
  long lwp = ptid.lwp ();
  ULONGEST tid = ptid.tid ();

  gdbpy_ref<> pid_obj = gdb_py_object_from_longest (pid);
  if (pid_obj == nullptr)
    return nullptr;
  gdbpy_ref<> lwp_obj = gdb_py_object_from_longest (lwp);
  if (lwp_obj == nullptr)
    return nullptr;
  gdbpy_ref<> tid_obj = gdb_py_object_from_ulongest (tid);
  if (tid_obj == nullptr)
    return nullptr;

  gdbpy_ref<> ret (PyTuple_New (3));
  if (ret == nullptr)
    return nullptr;

  /* Note that these steal references, hence the use of 'release'.  */
  if (PyTuple_SetItem (ret.get (), 0, pid_obj.release ()) < 0
      || PyTuple_SetItem (ret.get (), 1, lwp_obj.release ()) < 0
      || PyTuple_SetItem (ret.get (), 2, tid_obj.release ()) < 0)
    return nullptr;

  return ret;
}

/* Implementation of gdb.selected_thread () -> gdb.InferiorThread.
   Returns the selected thread object.  */

PyObject *
gdbpy_selected_thread (PyObject *self, PyObject *args)
{
  if (inferior_ptid != null_ptid)
    return thread_to_thread_object (inferior_thread ()).release ();

  Py_RETURN_NONE;
}

static int
gdbpy_initialize_thread ()
{
  return gdbpy_type_ready (&thread_object_type);
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_thread);



static gdb_PyGetSetDef thread_object_getset[] =
{
  gdbpy_dict_wrapper_cfg_dict_getter ("thread"),
  { "name", thpy_get_name, thpy_set_name,
    "The name of the thread, as set by the user or the OS.", NULL },
  { "details", thpy_get_details, NULL,
    "A target specific string containing extra thread state details.",
    NULL },
  { "num", thpy_get_num, NULL,
    "Per-inferior number of the thread, as assigned by GDB.", NULL },
  { "global_num", thpy_get_global_num, NULL,
    "Global number of the thread, as assigned by GDB.", NULL },
  { "ptid", thpy_get_ptid, NULL, "ID of the thread, as assigned by the OS.",
    NULL },
  { "ptid_string", thpy_get_ptid_string, nullptr,
    "A string representing ptid, as used by, for example, 'info threads'.",
    nullptr },
  { "inferior", thpy_get_inferior, NULL,
    "The Inferior object this thread belongs to.", NULL },

  { NULL }
};

static PyMethodDef thread_object_methods[] =
{
  { "is_valid", thpy_is_valid, METH_NOARGS,
    "is_valid () -> Boolean.\n\
Return true if this inferior thread is valid, false if not." },
  { "switch", thpy_switch, METH_NOARGS,
    "switch ()\n\
Makes this the GDB selected thread." },
  { "is_stopped", thpy_is_stopped, METH_NOARGS,
    "is_stopped () -> Boolean\n\
Return whether the thread is stopped." },
  { "is_running", thpy_is_running, METH_NOARGS,
    "is_running () -> Boolean\n\
Return whether the thread is running." },
  { "is_exited", thpy_is_exited, METH_NOARGS,
    "is_exited () -> Boolean\n\
Return whether the thread is exited." },
  { "handle", thpy_thread_handle, METH_NOARGS,
    "handle  () -> handle\n\
Return thread library specific handle for thread." },

  { NULL }
};

PyTypeObject thread_object_type =
{
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.InferiorThread",		  /*tp_name*/
  sizeof (thread_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  thpy_dealloc,			  /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  thpy_repr,			  /*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,		  /*tp_flags*/
  "GDB thread object",		  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  0,				  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  0,				  /* tp_iter */
  0,				  /* tp_iternext */
  thread_object_methods,	  /* tp_methods */
  0,				  /* tp_members */
  thread_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 */
};
