/* MI Command Set for GDB, the GNU debugger.

   Copyright (C) 2019-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/>.  */

/* GDB/MI commands implemented in Python.  */

#include "python-internal.h"
#include "arch-utils.h"
#include "charset.h"
#include "language.h"
#include "mi/mi-cmds.h"
#include "mi/mi-parse.h"
#include "cli/cli-cmds.h"
#include <string>

/* Debugging of Python MI commands.  */

static bool pymicmd_debug;

/* Implementation of "show debug py-micmd".  */

static void
show_pymicmd_debug (struct ui_file *file, int from_tty,
		    struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Python MI command debugging is %s.\n"), value);
}

/* Print a "py-micmd" debug statement.  */

#define pymicmd_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (pymicmd_debug, "py-micmd", fmt, ##__VA_ARGS__)

/* Print a "py-micmd" enter/exit debug statements.  */

#define PYMICMD_SCOPED_DEBUG_ENTER_EXIT \
  scoped_debug_enter_exit (pymicmd_debug, "py-micmd")

struct mi_command_py;

/* Representation of a Python gdb.MICommand object.  */

struct micmdpy_object : public PyObject
{
  /* The object representing this command in the MI command table.  This
     pointer can be nullptr if the command is not currently installed into
     the MI command table (see gdb.MICommand.installed property).  */
  struct mi_command_py *mi_command;

  /* The string representing the name of this command, without the leading
     dash.  This string is never nullptr once the Python object has been
     initialised.

     The memory for this string was allocated with malloc, and needs to be
     deallocated with free when the Python object is deallocated.

     When the MI_COMMAND field is not nullptr, then the mi_command_py
     object's name will point back to this string.  */
  char *mi_command_name;
};

/* The MI command implemented in Python.  */

struct mi_command_py : public mi_command
{
  /* Constructs a new mi_command_py object.  NAME is command name without
     leading dash.  OBJECT is a reference to a Python object implementing
     the command.  This object must inherit from gdb.MICommand and must
     implement the invoke method.  */

  mi_command_py (const char *name, micmdpy_object *object)
    : mi_command (name, nullptr),
      m_pyobj (gdbpy_ref<micmdpy_object>::new_reference (object))
  {
    pymicmd_debug_printf ("this = %p", this);
    m_pyobj->mi_command = this;
  }

  ~mi_command_py ()
  {
    /* The Python object representing a MI command contains a pointer back
       to this c++ object.  We can safely set this pointer back to nullptr
       now, to indicate the Python object no longer references a valid c++
       object.

       However, the Python object also holds the storage for our name
       string.  We can't clear that here as our parent's destructor might
       still want to reference that string.  Instead we rely on the Python
       object deallocator to free that memory, and reset the pointer.  */
    m_pyobj->mi_command = nullptr;

    pymicmd_debug_printf ("this = %p", this);
  };

  /* Validate that CMD_OBJ, a non-nullptr pointer, is installed into the MI
     command table correctly.  This function looks up the command in the MI
     command table and checks that the object we get back references
     CMD_OBJ.  This function is only intended for calling within a
     gdb_assert.  This function performs many assertions internally, and
     then always returns true.  */
  static void validate_installation (micmdpy_object *cmd_obj);

  /* Update M_PYOBJ to NEW_PYOBJ.  The pointer from M_PYOBJ that points
     back to this object is swapped with the pointer in NEW_PYOBJ, which
     must be nullptr, so that NEW_PYOBJ now points back to this object.
     Additionally our parent's name string is stored in M_PYOBJ, so we
     swap the name string with NEW_PYOBJ.

     Before this call M_PYOBJ is the Python object representing this MI
     command object.  After this call has completed, NEW_PYOBJ now
     represents this MI command object.  */
  void swap_python_object (micmdpy_object *new_pyobj)
  {
    /* Current object has a backlink, new object doesn't have a backlink.  */
    gdb_assert (m_pyobj->mi_command != nullptr);
    gdb_assert (new_pyobj->mi_command == nullptr);

    /* Clear the current M_PYOBJ's backlink, set NEW_PYOBJ's backlink.  */
    std::swap (new_pyobj->mi_command, m_pyobj->mi_command);

    /* Both object have names.  */
    gdb_assert (m_pyobj->mi_command_name != nullptr);
    gdb_assert (new_pyobj->mi_command_name != nullptr);

    /* mi_command::m_name is the string owned by the current object.  */
    gdb_assert (m_pyobj->mi_command_name == this->name ());

    /* The name in mi_command::m_name is owned by the current object.  Rather
       than changing the value of mi_command::m_name (which is not accessible
       from here) to point to the name owned by the new object, swap the names
       of the two objects, since we know they are identical strings.  */
    gdb_assert (streq (new_pyobj->mi_command_name, m_pyobj->mi_command_name));
    std::swap (new_pyobj->mi_command_name, m_pyobj->mi_command_name);

    /* Take a reference to the new object, drop the reference to the current
       object.  */
    m_pyobj = gdbpy_ref<micmdpy_object>::new_reference (new_pyobj);
  }

  /* Called when the MI command is invoked.  */
  virtual void invoke(struct mi_parse *parse) const override;

private:
  /* The Python object representing this MI command.  */
  gdbpy_ref<micmdpy_object> m_pyobj;
};

using mi_command_py_up = std::unique_ptr<mi_command_py>;

extern PyTypeObject micmdpy_object_type;

/* Holds a Python object containing the string 'invoke'.  */

static PyObject *invoke_cst;

/* Called when the MI command is invoked.  PARSE contains the parsed
   command line arguments from the user.  */

void
mi_command_py::invoke (struct mi_parse *parse) const
{
  PYMICMD_SCOPED_DEBUG_ENTER_EXIT;

  pymicmd_debug_printf ("this = %p, name = %s", this, name ());

  parse->parse_argv ();

  if (parse->argv == nullptr)
    error (_("Problem parsing arguments: %s %s"), parse->command.get (),
	   parse->args ());


  gdbpy_enter enter_py;

  /* Place all the arguments into a list which we pass as a single argument
     to the MI command's invoke method.  */
  gdbpy_ref<> argobj (PyList_New (parse->argc));
  if (argobj == nullptr)
    gdbpy_handle_exception ();

  for (int i = 0; i < parse->argc; ++i)
    {
      gdbpy_ref<> str (PyUnicode_Decode (parse->argv[i],
					 strlen (parse->argv[i]),
					 host_charset (), nullptr));
      if (PyList_SetItem (argobj.get (), i, str.release ()) < 0)
	gdbpy_handle_exception ();
    }

  gdb_assert (this->m_pyobj != nullptr);
  gdb_assert (PyErr_Occurred () == nullptr);
  gdbpy_ref<> results
    (PyObject_CallMethodObjArgs ((PyObject *) this->m_pyobj.get (), invoke_cst,
				 argobj.get (), nullptr));
  if (results == nullptr)
    gdbpy_handle_exception ();

  if (results != Py_None)
    {
      /* At the top-level, the results must be a dictionary.  */
      if (!PyDict_Check (results.get ()))
	gdbpy_error (_("Result from invoke must be a dictionary"));
      serialize_mi_results (results.get ());
    }
}

/* See declaration above.  */

void
mi_command_py::validate_installation (micmdpy_object *cmd_obj)
{
  gdb_assert (cmd_obj != nullptr);
  mi_command_py *cmd = cmd_obj->mi_command;
  gdb_assert (cmd != nullptr);
  const char *name = cmd_obj->mi_command_name;
  gdb_assert (name != nullptr);
  gdb_assert (name == cmd->name ());
  mi_command *mi_cmd = mi_cmd_lookup (name);
  gdb_assert (mi_cmd == cmd);
  gdb_assert (cmd->m_pyobj == cmd_obj);
}

/* Return CMD as an mi_command_py if it is a Python MI command, else
   nullptr.  */

static mi_command_py *
as_mi_command_py (mi_command *cmd)
{
  return dynamic_cast<mi_command_py *> (cmd);
}

/* Uninstall OBJ, making the MI command represented by OBJ unavailable for
   use by the user.  On success 0 is returned, otherwise -1 is returned
   and a Python exception will be set.  */

static int
micmdpy_uninstall_command (micmdpy_object *obj)
{
  PYMICMD_SCOPED_DEBUG_ENTER_EXIT;

  gdb_assert (obj->mi_command != nullptr);
  gdb_assert (obj->mi_command_name != nullptr);

  pymicmd_debug_printf ("name = %s", obj->mi_command_name);

  /* Remove the command from the internal MI table of commands.  This will
     cause the mi_command_py object to be deleted, which will clear the
     backlink in OBJ.  */
  bool removed = remove_mi_cmd_entry (obj->mi_command->name ());
  gdb_assert (removed);
  gdb_assert (obj->mi_command == nullptr);

  return 0;
}

/* Install OBJ as a usable MI command.  Return 0 on success, and -1 on
   error, in which case, a Python error will have been set.

   After successful completion the command name associated with OBJ will
   be installed in the MI command table (so it can be found if the user
   enters that command name), additionally, OBJ will have been added to
   the gdb._mi_commands dictionary (using the command name as its key),
   this will ensure that OBJ remains live even if the user gives up all
   references.  */

static int
micmdpy_install_command (micmdpy_object *obj)
{
  PYMICMD_SCOPED_DEBUG_ENTER_EXIT;

  gdb_assert (obj->mi_command == nullptr);
  gdb_assert (obj->mi_command_name != nullptr);

  pymicmd_debug_printf ("name = %s", obj->mi_command_name);

  /* Look up this command name in MI_COMMANDS, a command with this name may
     already exist.  */
  mi_command *cmd = mi_cmd_lookup (obj->mi_command_name);
  mi_command_py *cmd_py = as_mi_command_py (cmd);

  if (cmd != nullptr && cmd_py == nullptr)
    {
      /* There is already an MI command registered with that name, and it's not
	 a Python one.  Forbid replacing a non-Python MI command.  */
      PyErr_SetString (PyExc_RuntimeError,
		       _("unable to add command, name is already in use"));
      return -1;
    }

  if (cmd_py != nullptr)
    {
      /* There is already a Python MI command registered with that name, swap
	 in the new gdb.MICommand implementation.  */
      cmd_py->swap_python_object (obj);
    }
  else
    {
      /* There's no MI command registered with that name at all, create one.  */
      mi_command_py_up mi_cmd (new mi_command_py (obj->mi_command_name, obj));

      /* Add the command to the gdb internal MI command table.  */
      bool result = insert_mi_cmd_entry (std::move (mi_cmd));
      gdb_assert (result);
    }

  return 0;
}

/* Implement gdb.MICommand.__init__.  The init method takes the name of
   the MI command as the first argument, which must be a string, starting
   with a single dash.  */

static int
micmdpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  PYMICMD_SCOPED_DEBUG_ENTER_EXIT;

  micmdpy_object *cmd = (micmdpy_object *) self;

  static const char *keywords[] = { "name", nullptr };
  const char *name;

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "s", keywords,
					&name))
    return -1;

  /* Validate command name */
  const int name_len = strlen (name);
  if (name_len == 0)
    {
      PyErr_SetString (PyExc_ValueError, _("MI command name is empty."));
      return -1;
    }
  else if ((name_len < 2) || (name[0] != '-') || !c_isalnum (name[1]))
    {
      PyErr_SetString (PyExc_ValueError,
		       _("MI command name does not start with '-'"
			 " followed by at least one letter or digit."));
      return -1;
    }
  else
    {
      for (int i = 2; i < name_len; i++)
	{
	  if (!c_isalnum (name[i]) && name[i] != '-')
	    {
	      PyErr_Format
		(PyExc_ValueError,
		 _("MI command name contains invalid character: %c."),
		 name[i]);
	      return -1;
	    }
	}

      /* Skip over the leading dash.  For the rest of this function the
	 dash is not important.  */
      ++name;
    }

  /* If this object already has a name set, then this object has been
     initialized before.  We handle this case a little differently.  */
  if (cmd->mi_command_name != nullptr)
    {
      /* First, we don't allow the user to change the MI command name.
	 Supporting this would be tricky as we would need to delete the
	 mi_command_py from the MI command table, however, the user might
	 be trying to perform this reinitialization from within the very
	 command we're about to delete... it all gets very messy.

	 So, for now at least, we don't allow this.  This doesn't seem like
	 an excessive restriction.  */
      if (!streq (cmd->mi_command_name, name))
	{
	  PyErr_SetString
	    (PyExc_ValueError,
	     _("can't reinitialize object with a different command name"));
	  return -1;
	}

      /* If there's already an object registered with the MI command table,
	 then we're done.  That object must be a mi_command_py, which
	 should reference back to this micmdpy_object.  */
      if (cmd->mi_command != nullptr)
	{
	  mi_command_py::validate_installation (cmd);
	  return 0;
	}
    }
  else
    cmd->mi_command_name = xstrdup (name);

  /* Now we can install this mi_command_py in the MI command table.  */
  return micmdpy_install_command (cmd);
}

/* Called when a gdb.MICommand object is deallocated.  */

static void
micmdpy_dealloc (PyObject *obj)
{
  PYMICMD_SCOPED_DEBUG_ENTER_EXIT;

  micmdpy_object *cmd = (micmdpy_object *) obj;

  /* If the Python object failed to initialize, then the name field might
     be nullptr.  */
  pymicmd_debug_printf ("obj = %p, name = %s", cmd,
			(cmd->mi_command_name == nullptr
			 ? "(null)" : cmd->mi_command_name));

  /* As the mi_command_py object holds a reference to the micmdpy_object,
     the only way the dealloc function can be called is if the mi_command_py
     object has been deleted, in which case the following assert will
     hold.  */
  gdb_assert (cmd->mi_command == nullptr);

  /* Free the memory that holds the command name.  */
  xfree (cmd->mi_command_name);
  cmd->mi_command_name = nullptr;

  /* Finally, free the memory for this Python object.  */
  Py_TYPE (obj)->tp_free (obj);
}

/* Python initialization for the MI commands components.  */

static int
gdbpy_initialize_micommands ()
{
  micmdpy_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&micmdpy_object_type) < 0)
    return -1;

  invoke_cst = PyUnicode_FromString ("invoke");
  if (invoke_cst == nullptr)
    return -1;

  return 0;
}

/* Cleanup just before GDB shuts down the Python interpreter.  */

static void
gdbpy_finalize_micommands ()
{
  /* mi_command_py objects hold references to micmdpy_object objects.  They must
     be dropped before the Python interpreter is finalized.  Do so by removing
     those MI command entries, thus deleting the mi_command_py objects.  */
  remove_mi_cmd_entries ([] (mi_command *cmd)
    {
      return as_mi_command_py (cmd) != nullptr;
    });
}

/* Get the gdb.MICommand.name attribute, returns a string, the name of this
   MI command.  */

static PyObject *
micmdpy_get_name (PyObject *self, void *closure)
{
  struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self;

  gdb_assert (micmd_obj->mi_command_name != nullptr);
  std::string name_str = string_printf ("-%s", micmd_obj->mi_command_name);
  return PyUnicode_FromString (name_str.c_str ());
}

/* Get the gdb.MICommand.installed property.  Returns true if this MI
   command is installed into the MI command table, otherwise returns
   false.  */

static PyObject *
micmdpy_get_installed (PyObject *self, void *closure)
{
  struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self;

  if (micmd_obj->mi_command == nullptr)
    Py_RETURN_FALSE;
  Py_RETURN_TRUE;
}

/* Set the gdb.MICommand.installed property.  The property can be set to
   either true or false.  Setting the property to true will cause the
   command to be installed into the MI command table (if it isn't
   already), while setting this property to false will cause the command
   to be removed from the MI command table (if it is present).  */

static int
micmdpy_set_installed (PyObject *self, PyObject *newvalue, void *closure)
{
  struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self;

  if (!PyBool_Check (newvalue))
    {
      PyErr_Format (PyExc_TypeError,
		    _("gdb.MICommand.installed must be set to a bool, not %s"),
		    newvalue == Py_None ? "None" : gdbpy_py_obj_tp_name (newvalue));
      return -1;
    }

  bool installed_p = newvalue == Py_True;

  if (installed_p == (micmd_obj->mi_command != nullptr))
    return 0;

  if (installed_p)
    return micmdpy_install_command (micmd_obj);
  else
    return micmdpy_uninstall_command (micmd_obj);
}

/* The gdb.MICommand properties.   */

static gdb_PyGetSetDef micmdpy_object_getset[] = {
  { "name", micmdpy_get_name, nullptr, "The command's name.", nullptr },
  { "installed", micmdpy_get_installed, micmdpy_set_installed,
    "Is this command installed for use.", nullptr },
  { nullptr }	/* Sentinel.  */
};

/* The gdb.MICommand descriptor.  */

PyTypeObject micmdpy_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0) "gdb.MICommand", /*tp_name */
  sizeof (micmdpy_object),			   /*tp_basicsize */
  0,						   /*tp_itemsize */
  micmdpy_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 mi-command 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 */
  micmdpy_object_getset,			   /* tp_getset */
  0,						   /* tp_base */
  0,						   /* tp_dict */
  0,						   /* tp_descr_get */
  0,						   /* tp_descr_set */
  0,						   /* tp_dictoffset */
  micmdpy_init,					   /* tp_init */
  0,						   /* tp_alloc */
};

INIT_GDB_FILE (py_micmd)
{
  add_setshow_boolean_cmd
    ("py-micmd", class_maintenance, &pymicmd_debug,
     _("Set Python micmd debugging."),
     _("Show Python micmd debugging."),
     _("When on, Python micmd debugging is enabled."),
     nullptr,
     show_pymicmd_debug,
     &setdebuglist, &showdebuglist);
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_micommands, gdbpy_finalize_micommands);
