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

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

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

#include "defs.h"
#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
{
  PyObject_HEAD

  /* 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 (strcmp (new_pyobj->mi_command_name,
			m_pyobj->mi_command_name) == 0);
    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
	CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("micmdpy_object");

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

static PyObject *invoke_cst;

/* Convert KEY_OBJ into a string that can be used as a field name in MI
   output.  KEY_OBJ must be a Python string object, and must only contain
   characters suitable for use as an MI field name.

   If KEY_OBJ is not a string, or if KEY_OBJ contains invalid characters,
   then an error is thrown.  Otherwise, KEY_OBJ is converted to a string
   and returned.  */

static gdb::unique_xmalloc_ptr<char>
py_object_to_mi_key (PyObject *key_obj)
{
  /* The key must be a string.  */
  if (!PyUnicode_Check (key_obj))
    {
      gdbpy_ref<> key_repr (PyObject_Repr (key_obj));
      gdb::unique_xmalloc_ptr<char> key_repr_string;
      if (key_repr != nullptr)
	key_repr_string = python_string_to_target_string (key_repr.get ());
      if (key_repr_string == nullptr)
	gdbpy_handle_exception ();

      gdbpy_error (_("non-string object used as key: %s"),
		   key_repr_string.get ());
    }

  gdb::unique_xmalloc_ptr<char> key_string
    = python_string_to_target_string (key_obj);
  if (key_string == nullptr)
    gdbpy_handle_exception ();

  /* Predicate function, returns true if NAME is a valid field name for use
     in MI result output, otherwise, returns false.  */
  auto is_valid_key_name = [] (const char *name) -> bool
  {
    gdb_assert (name != nullptr);

    if (*name == '\0' || !isalpha (*name))
      return false;

    for (; *name != '\0'; ++name)
      if (!isalnum (*name) && *name != '_' && *name != '-')
	return false;

    return true;
  };

  if (!is_valid_key_name (key_string.get ()))
    {
      if (*key_string.get () == '\0')
	gdbpy_error (_("Invalid empty key in MI result"));
      else
	gdbpy_error (_("Invalid key in MI result: %s"), key_string.get ());
    }

  return key_string;
}

/* Serialize RESULT and print it in MI format to the current_uiout.
   FIELD_NAME is used as the name of this result field.

   RESULT can be a dictionary, a sequence, an iterator, or an object that
   can be converted to a string, these are converted to the matching MI
   output format (dictionaries as tuples, sequences and iterators as lists,
   and strings as named fields).

   If anything goes wrong while formatting the output then an error is
   thrown.

   This function is the recursive inner core of serialize_mi_result, and
   should only be called from that function.  */

static void
serialize_mi_result_1 (PyObject *result, const char *field_name)
{
  struct ui_out *uiout = current_uiout;

  if (PyDict_Check (result))
    {
      PyObject *key, *value;
      Py_ssize_t pos = 0;
      ui_out_emit_tuple tuple_emitter (uiout, field_name);
      while (PyDict_Next (result, &pos, &key, &value))
	{
	  gdb::unique_xmalloc_ptr<char> key_string
	    (py_object_to_mi_key (key));
	  serialize_mi_result_1 (value, key_string.get ());
	}
    }
  else if (PySequence_Check (result) && !PyUnicode_Check (result))
    {
      ui_out_emit_list list_emitter (uiout, field_name);
      Py_ssize_t len = PySequence_Size (result);
      if (len == -1)
	gdbpy_handle_exception ();
      for (Py_ssize_t i = 0; i < len; ++i)
	{
	  gdbpy_ref<> item (PySequence_ITEM (result, i));
	  if (item == nullptr)
	    gdbpy_handle_exception ();
	  serialize_mi_result_1 (item.get (), nullptr);
	}
    }
  else if (PyIter_Check (result))
    {
      gdbpy_ref<> item;
      ui_out_emit_list list_emitter (uiout, field_name);
      while (true)
	{
	  item.reset (PyIter_Next (result));
	  if (item == nullptr)
	    {
	      if (PyErr_Occurred () != nullptr)
		gdbpy_handle_exception ();
	      break;
	    }
	  serialize_mi_result_1 (item.get (), nullptr);
	}
    }
  else
    {
      gdb::unique_xmalloc_ptr<char> string (gdbpy_obj_to_string (result));
      if (string == nullptr)
	gdbpy_handle_exception ();
      uiout->field_string (field_name, string.get ());
    }
}

/* Serialize RESULT and print it in MI format to the current_uiout.

   This function handles the top-level result initially returned from the
   invoke method of the Python command implementation.  At the top-level
   the result must be a dictionary.  The values within this dictionary can
   be a wider range of types.  Handling the values of the top-level
   dictionary is done by serialize_mi_result_1, see that function for more
   details.

   If anything goes wrong while parsing and printing the MI output then an
   error is thrown.  */

static void
serialize_mi_result (PyObject *result)
{
  /* At the top-level, the result must be a dictionary.  */

  if (!PyDict_Check (result))
    gdbpy_error (_("Result from invoke must be a dictionary"));

  PyObject *key, *value;
  Py_ssize_t pos = 0;
  while (PyDict_Next (result, &pos, &key, &value))
    {
      gdb::unique_xmalloc_ptr<char> key_string
	(py_object_to_mi_key (key));
      serialize_mi_result_1 (value, key_string.get ());
    }
}

/* 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 ());

  mi_parse_argv (parse->args, parse);

  if (parse->argv == nullptr)
    error (_("Problem parsing arguments: %s %s"), parse->command, 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<> result
    (PyObject_CallMethodObjArgs ((PyObject *) this->m_pyobj.get (), invoke_cst,
				 argobj.get (), nullptr));
  if (result == nullptr)
    gdbpy_handle_exception ();

  if (result != Py_None)
    serialize_mi_result (result.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] != '-') || !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 (!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 (strcmp (cmd->mi_command_name, name) != 0)
	{
	  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.  */

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

  if (gdb_pymodule_addobject (gdb_module, "MICommand",
			      (PyObject *) &micmdpy_object_type)
      < 0)
    return -1;

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

  return 0;
}

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;

  bool installed_p = PyObject_IsTrue (newvalue);
  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 */
};

void _initialize_py_micmd ();
void
_initialize_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);
}
