/* Python interface to inferior threads.

   Copyright (C) 2009-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 "gdbthread.h"
#include "inferior.h"
#include "python-internal.h"

extern PyTypeObject
  thread_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("thread_object");

/* 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 NULL;

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

  thread_obj->thread = tp;
  thread_obj->inf_obj = (PyObject *) inf_obj.release ();

  return thread_obj;
}

static void
thpy_dealloc (PyObject *self)
{
  Py_DECREF (((thread_object *) self)->inf_obj);
  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)
    {
      GDB_PY_HANDLE_EXCEPTION (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);
}

/* 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)
    {
      GDB_PY_HANDLE_EXCEPTION (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::byte_vector hv;

  try
    {
      hv = target_thread_info_to_thread_handle (thread_obj->thread);
    }
  catch (const gdb_exception &except)
    {
      GDB_PY_HANDLE_EXCEPTION (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;
}

/* Return a reference to a new Python object representing a ptid_t.
   The object is a tuple containing (pid, lwp, tid). */
PyObject *
gdbpy_create_ptid_object (ptid_t ptid)
{
  int pid;
  long lwp;
  ULONGEST tid;
  PyObject *ret;

  ret = PyTuple_New (3);
  if (!ret)
    return NULL;

  pid = ptid.pid ();
  lwp = ptid.lwp ();
  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;

  /* Note that these steal references, hence the use of 'release'.  */
  PyTuple_SET_ITEM (ret, 0, pid_obj.release ());
  PyTuple_SET_ITEM (ret, 1, lwp_obj.release ());
  PyTuple_SET_ITEM (ret, 2, tid_obj.release ());

  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;
}

int
gdbpy_initialize_thread (void)
{
  if (PyType_Ready (&thread_object_type) < 0)
    return -1;

  return gdb_pymodule_addobject (gdb_module, "InferiorThread",
				 (PyObject *) &thread_object_type);
}

static gdb_PyGetSetDef thread_object_getset[]
  = { { "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 },
      { "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*/
  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,					/*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 */
};
