/* gdb commands implemented in Python

   Copyright (C) 2008-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 "arch-utils.h"
#include "value.h"
#include "python-internal.h"
#include "charset.h"
#include "gdbcmd.h"
#include "cli/cli-decode.h"
#include "completer.h"
#include "language.h"

/* Struct representing built-in completion types.  */
struct cmdpy_completer
{
  /* Python symbol name.  */
  const char *name;
  /* Completion function.  */
  completer_ftype *completer;
};

static const struct cmdpy_completer completers[] = {
  { "COMPLETE_NONE", noop_completer },
  { "COMPLETE_FILENAME", filename_completer },
  { "COMPLETE_LOCATION", location_completer },
  { "COMPLETE_COMMAND", command_completer },
  { "COMPLETE_SYMBOL", symbol_completer },
  { "COMPLETE_EXPRESSION", expression_completer },
};

#define N_COMPLETERS (sizeof (completers) / sizeof (completers[0]))

/* A gdb command.  For the time being only ordinary commands (not
   set/show commands) are allowed.  */
struct cmdpy_object
{
  PyObject_HEAD

    /* The corresponding gdb command object, or NULL if the command is
     no longer installed.  */
    struct cmd_list_element *command;

  /* A prefix command requires storage for a list of its sub-commands.
     A pointer to this is passed to add_prefix_command, and to add_cmd
     for sub-commands of that prefix.  If this Command is not a prefix
     command, then this field is unused.  */
  struct cmd_list_element *sub_list;
};

extern PyTypeObject
  cmdpy_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("cmdpy_object");

/* Constants used by this module.  */
static PyObject *invoke_cst;
static PyObject *complete_cst;

/* Python function which wraps dont_repeat.  */
static PyObject *
cmdpy_dont_repeat (PyObject *self, PyObject *args)
{
  dont_repeat ();
  Py_RETURN_NONE;
}

/* Called if the gdb cmd_list_element is destroyed.  */

static void
cmdpy_destroyer (struct cmd_list_element *self, void *context)
{
  gdbpy_enter enter_py;

  /* Release our hold on the command object.  */
  gdbpy_ref<cmdpy_object> cmd ((cmdpy_object *) context);
  cmd->command = NULL;
}

/* Called by gdb to invoke the command.  */

static void
cmdpy_function (const char *args, int from_tty, cmd_list_element *command)
{
  cmdpy_object *obj = (cmdpy_object *) command->context ();

  gdbpy_enter enter_py;

  if (!obj)
    error (_ ("Invalid invocation of Python command object."));
  if (!PyObject_HasAttr ((PyObject *) obj, invoke_cst))
    {
      if (obj->command->is_prefix ())
	{
	  /* A prefix command does not need an invoke method.  */
	  return;
	}
      error (_ ("Python command object missing 'invoke' method."));
    }

  if (!args)
    args = "";
  gdbpy_ref<> argobj (PyUnicode_Decode (args, strlen (args), host_charset (),
					NULL));
  if (argobj == NULL)
    {
      gdbpy_print_stack ();
      error (_ ("Could not convert arguments to Python string."));
    }

  gdbpy_ref<> ttyobj (PyBool_FromLong (from_tty));
  gdbpy_ref<> result (PyObject_CallMethodObjArgs ((PyObject *) obj, invoke_cst,
						  argobj.get (), ttyobj.get (),
						  NULL));

  if (result == NULL)
    gdbpy_handle_exception ();
}

/* Helper function for the Python command completers (both "pure"
   completer and brkchar handler).  This function takes COMMAND, TEXT
   and WORD and tries to call the Python method for completion with
   these arguments.

   This function is usually called twice: once when we are figuring out
   the break characters to be used, and another to perform the real
   completion itself.  The reason for this two step dance is that we
   need to know the set of "brkchars" to use early on, before we
   actually try to perform the completion.  But if a Python command
   supplies a "complete" method then we have to call that method
   first: it may return as its result the kind of completion to
   perform and that will in turn specify which brkchars to use.  IOW,
   we need the result of the "complete" method before we actually
   perform the completion.  The only situation when this function is
   not called twice is when the user uses the "complete" command: in
   this scenario, there is no call to determine the "brkchars".

   Ideally, it would be nice to cache the result of the first call (to
   determine the "brkchars") and return this value directly in the
   second call (to perform the actual completion).  However, due to
   the peculiarity of the "complete" command mentioned above, it is
   possible to put GDB in a bad state if you perform a TAB-completion
   and then a "complete"-completion sequentially.  Therefore, we just
   recalculate everything twice for TAB-completions.

   This function returns a reference to the PyObject representing the
   Python method call.  */

static gdbpy_ref<>
cmdpy_completer_helper (struct cmd_list_element *command, const char *text,
			const char *word)
{
  cmdpy_object *obj = (cmdpy_object *) command->context ();

  if (obj == NULL)
    error (_ ("Invalid invocation of Python command object."));
  if (!PyObject_HasAttr ((PyObject *) obj, complete_cst))
    {
      /* If there is no complete method, don't error.  */
      return NULL;
    }

  gdbpy_ref<> textobj (PyUnicode_Decode (text, strlen (text), host_charset (),
					 NULL));
  if (textobj == NULL)
    error (_ ("Could not convert argument to Python string."));

  gdbpy_ref<> wordobj;
  if (word == NULL)
    {
      /* "brkchars" phase.  */
      wordobj = gdbpy_ref<>::new_reference (Py_None);
    }
  else
    {
      wordobj.reset (PyUnicode_Decode (word, strlen (word), host_charset (),
				       NULL));
      if (wordobj == NULL)
	error (_ ("Could not convert argument to Python string."));
    }

  gdbpy_ref<> resultobj (PyObject_CallMethodObjArgs (
    (PyObject *) obj, complete_cst, textobj.get (), wordobj.get (), NULL));
  if (resultobj == NULL)
    {
      /* Just swallow errors here.  */
      PyErr_Clear ();
    }

  return resultobj;
}

/* Python function called to determine the break characters of a
   certain completer.  We are only interested in knowing if the
   completer registered by the user will return one of the integer
   codes (see COMPLETER_* symbols).  */

static void
cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
				 completion_tracker &tracker, const char *text,
				 const char *word)
{
  gdbpy_enter enter_py;

  /* Calling our helper to obtain a reference to the PyObject of the Python
     function.  */
  gdbpy_ref<> resultobj = cmdpy_completer_helper (command, text, word);

  /* Check if there was an error.  */
  if (resultobj == NULL)
    return;

  if (PyLong_Check (resultobj.get ()))
    {
      /* User code may also return one of the completion constants,
	 thus requesting that sort of completion.  We are only
	 interested in this kind of return.  */
      long value;

      if (!gdb_py_int_as_long (resultobj.get (), &value))
	{
	  /* Ignore.  */
	  PyErr_Clear ();
	}
      else if (value >= 0 && value < (long) N_COMPLETERS)
	{
	  completer_handle_brkchars_ftype *brkchars_fn;

	  /* This is the core of this function.  Depending on which
	     completer type the Python function returns, we have to
	     adjust the break characters accordingly.  */
	  brkchars_fn = (completer_handle_brkchars_func_for_completer (
	    completers[value].completer));
	  brkchars_fn (command, tracker, text, word);
	}
    }
}

/* Called by gdb for command completion.  */

static void
cmdpy_completer (struct cmd_list_element *command, completion_tracker &tracker,
		 const char *text, const char *word)
{
  gdbpy_enter enter_py;

  /* Calling our helper to obtain a reference to the PyObject of the Python
     function.  */
  gdbpy_ref<> resultobj = cmdpy_completer_helper (command, text, word);

  /* If the result object of calling the Python function is NULL, it
     means that there was an error.  In this case, just give up.  */
  if (resultobj == NULL)
    return;

  if (PyLong_Check (resultobj.get ()))
    {
      /* User code may also return one of the completion constants,
	 thus requesting that sort of completion.  */
      long value;

      if (!gdb_py_int_as_long (resultobj.get (), &value))
	{
	  /* Ignore.  */
	  PyErr_Clear ();
	}
      else if (value >= 0 && value < (long) N_COMPLETERS)
	completers[value].completer (command, tracker, text, word);
    }
  else
    {
      gdbpy_ref<> iter (PyObject_GetIter (resultobj.get ()));

      if (iter == NULL)
	return;

      bool got_matches = false;
      while (true)
	{
	  gdbpy_ref<> elt (PyIter_Next (iter.get ()));
	  if (elt == NULL)
	    break;

	  if (!gdbpy_is_string (elt.get ()))
	    {
	      /* Skip problem elements.  */
	      continue;
	    }
	  gdb::unique_xmalloc_ptr<char> item (
	    python_string_to_host_string (elt.get ()));
	  if (item == NULL)
	    {
	      /* Skip problem elements.  */
	      PyErr_Clear ();
	      continue;
	    }
	  tracker.add_completion (std::move (item));
	  got_matches = true;
	}

      /* If we got some results, ignore problems.  Otherwise, report
	 the problem.  */
      if (got_matches && PyErr_Occurred ())
	PyErr_Clear ();
    }
}

/* Helper for cmdpy_init which locates the command list to use and
   pulls out the command name.

   NAME is the command name list.  The final word in the list is the
   name of the new command.  All earlier words must be existing prefix
   commands.

   *BASE_LIST is set to the final prefix command's list of
   *sub-commands.

   START_LIST is the list in which the search starts.

   This function returns the name of the new command.  On error sets the Python
   error and returns NULL.  */

gdb::unique_xmalloc_ptr<char>
gdbpy_parse_command_name (const char *name,
			  struct cmd_list_element ***base_list,
			  struct cmd_list_element **start_list)
{
  struct cmd_list_element *elt;
  int len = strlen (name);
  int i, lastchar;
  const char *prefix_text2;

  /* Skip trailing whitespace.  */
  for (i = len - 1; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
    ;
  if (i < 0)
    {
      PyErr_SetString (PyExc_RuntimeError, _ ("No command name found."));
      return NULL;
    }
  lastchar = i;

  /* Find first character of the final word.  */
  for (; i > 0 && valid_cmd_char_p (name[i - 1]); --i)
    ;

  gdb::unique_xmalloc_ptr<char> result ((char *) xmalloc (lastchar - i + 2));
  memcpy (result.get (), &name[i], lastchar - i + 1);
  result.get ()[lastchar - i + 1] = '\0';

  /* Skip whitespace again.  */
  for (--i; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
    ;
  if (i < 0)
    {
      *base_list = start_list;
      return result;
    }

  std::string prefix_text (name, i + 1);

  prefix_text2 = prefix_text.c_str ();
  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
  if (elt == NULL || elt == CMD_LIST_AMBIGUOUS)
    {
      PyErr_Format (PyExc_RuntimeError,
		    _ ("Could not find command prefix %s."),
		    prefix_text.c_str ());
      return NULL;
    }

  if (elt->is_prefix ())
    {
      *base_list = elt->subcommands;
      return result;
    }

  PyErr_Format (PyExc_RuntimeError, _ ("'%s' is not a prefix command."),
		prefix_text.c_str ());
  return NULL;
}

/* Object initializer; sets up gdb-side structures for command.

   Use: __init__(NAME, COMMAND_CLASS [, COMPLETER_CLASS][, PREFIX]]).

   NAME is the name of the command.  It may consist of multiple words,
   in which case the final word is the name of the new command, and
   earlier words must be prefix commands.

   COMMAND_CLASS is the kind of command.  It should be one of the COMMAND_*
   constants defined in the gdb module.

   COMPLETER_CLASS is the kind of completer.  If not given, the
   "complete" method will be used.  Otherwise, it should be one of the
   COMPLETE_* constants defined in the gdb module.

   If PREFIX is True, then this command is a prefix command.

   The documentation for the command is taken from the doc string for
   the python class.  */

static int
cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
{
  cmdpy_object *obj = (cmdpy_object *) self;
  const char *name;
  int cmdtype;
  int completetype = -1;
  struct cmd_list_element **cmd_list;
  static const char *keywords[]
    = { "name", "command_class", "completer_class", "prefix", NULL };
  PyObject *is_prefix_obj = NULL;
  bool is_prefix = false;

  if (obj->command)
    {
      /* Note: this is apparently not documented in Python.  We return
	 0 for success, -1 for failure.  */
      PyErr_Format (PyExc_RuntimeError,
		    _ ("Command object already initialized."));
      return -1;
    }

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "si|iO", keywords, &name,
					&cmdtype, &completetype,
					&is_prefix_obj))
    return -1;

  if (cmdtype != no_class && cmdtype != class_run && cmdtype != class_vars
      && cmdtype != class_stack && cmdtype != class_files
      && cmdtype != class_support && cmdtype != class_info
      && cmdtype != class_breakpoint && cmdtype != class_trace
      && cmdtype != class_obscure && cmdtype != class_maintenance
      && cmdtype != class_user && cmdtype != class_tui)
    {
      PyErr_Format (PyExc_RuntimeError, _ ("Invalid command class argument."));
      return -1;
    }

  if (completetype < -1 || completetype >= (int) N_COMPLETERS)
    {
      PyErr_Format (PyExc_RuntimeError,
		    _ ("Invalid completion type argument."));
      return -1;
    }

  gdb::unique_xmalloc_ptr<char> cmd_name
    = gdbpy_parse_command_name (name, &cmd_list, &cmdlist);
  if (cmd_name == nullptr)
    return -1;

  if (is_prefix_obj != NULL)
    {
      int cmp = PyObject_IsTrue (is_prefix_obj);
      if (cmp < 0)
	return -1;

      is_prefix = cmp > 0;
    }

  gdb::unique_xmalloc_ptr<char> docstring = nullptr;
  if (PyObject_HasAttr (self, gdbpy_doc_cst))
    {
      gdbpy_ref<> ds_obj (PyObject_GetAttr (self, gdbpy_doc_cst));

      if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ()))
	{
	  docstring = python_string_to_host_string (ds_obj.get ());
	  if (docstring == nullptr)
	    return -1;
	  docstring = gdbpy_fix_doc_string_indentation (std::move (docstring));
	}
    }
  if (docstring == nullptr)
    docstring = make_unique_xstrdup (_ ("This command is not documented."));

  gdbpy_ref<> self_ref = gdbpy_ref<>::new_reference (self);

  try
    {
      struct cmd_list_element *cmd;

      if (is_prefix)
	{
	  int allow_unknown;

	  /* If we have our own "invoke" method, then allow unknown
	     sub-commands.  */
	  allow_unknown = PyObject_HasAttr (self, invoke_cst);
	  cmd = add_prefix_cmd (cmd_name.get (), (enum command_class) cmdtype,
				NULL, docstring.release (), &obj->sub_list,
				allow_unknown, cmd_list);
	}
      else
	cmd = add_cmd (cmd_name.get (), (enum command_class) cmdtype,
		       docstring.release (), cmd_list);

      /* If successful, the above takes ownership of the name, since we set
         name_allocated, so release it.  */
      cmd_name.release ();

      /* There appears to be no API to set this.  */
      cmd->func = cmdpy_function;
      cmd->destroyer = cmdpy_destroyer;
      cmd->doc_allocated = 1;
      cmd->name_allocated = 1;

      obj->command = cmd;
      cmd->set_context (self_ref.release ());
      set_cmd_completer (cmd, ((completetype == -1)
				 ? cmdpy_completer
				 : completers[completetype].completer));
      if (completetype == -1)
	set_cmd_completer_handle_brkchars (cmd,
					   cmdpy_completer_handle_brkchars);
    }
  catch (const gdb_exception &except)
    {
      gdbpy_convert_exception (except);
      return -1;
    }

  return 0;
}

/* Initialize the 'commands' code.  */

int
gdbpy_initialize_commands (void)
{
  int i;

  cmdpy_object_type.tp_new = PyType_GenericNew;
  if (PyType_Ready (&cmdpy_object_type) < 0)
    return -1;

  /* Note: alias and user are special.  */
  if (PyModule_AddIntConstant (gdb_module, "COMMAND_NONE", no_class) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_RUNNING", class_run) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_DATA", class_vars) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_STACK", class_stack) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_FILES", class_files) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_SUPPORT", class_support)
	   < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_STATUS", class_info) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_BREAKPOINTS",
				  class_breakpoint)
	   < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_TRACEPOINTS",
				  class_trace)
	   < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_OBSCURE", class_obscure)
	   < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_MAINTENANCE",
				  class_maintenance)
	   < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_USER", class_user) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_TUI", class_tui) < 0)
    return -1;

  for (i = 0; i < N_COMPLETERS; ++i)
    {
      if (PyModule_AddIntConstant (gdb_module, completers[i].name, i) < 0)
	return -1;
    }

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

  invoke_cst = PyUnicode_FromString ("invoke");
  if (invoke_cst == NULL)
    return -1;
  complete_cst = PyUnicode_FromString ("complete");
  if (complete_cst == NULL)
    return -1;

  return 0;
}

static PyMethodDef cmdpy_object_methods[]
  = { { "dont_repeat", cmdpy_dont_repeat, METH_NOARGS,
	"Prevent command repetition when user enters empty line." },

      { 0 } };

PyTypeObject cmdpy_object_type = {
  PyVarObject_HEAD_INIT (NULL, 0) "gdb.Command", /*tp_name*/
  sizeof (cmdpy_object),			 /*tp_basicsize*/
  0,						 /*tp_itemsize*/
  0,						 /*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 command object",				 /* tp_doc */
  0,						 /* tp_traverse */
  0,						 /* tp_clear */
  0,						 /* tp_richcompare */
  0,						 /* tp_weaklistoffset */
  0,						 /* tp_iter */
  0,						 /* tp_iternext */
  cmdpy_object_methods,				 /* tp_methods */
  0,						 /* tp_members */
  0,						 /* tp_getset */
  0,						 /* tp_base */
  0,						 /* tp_dict */
  0,						 /* tp_descr_get */
  0,						 /* tp_descr_set */
  0,						 /* tp_dictoffset */
  cmdpy_init,					 /* tp_init */
  0,						 /* tp_alloc */
};

/* Utility to build a buildargv-like result from ARGS.
   This intentionally parses arguments the way libiberty/argv.c:buildargv
   does.  It splits up arguments in a reasonable way, and we want a standard
   way of parsing arguments.  Several gdb commands use buildargv to parse their
   arguments.  Plus we want to be able to write compatible python
   implementations of gdb commands.  */

PyObject *
gdbpy_string_to_argv (PyObject *self, PyObject *args)
{
  const char *input;

  if (!PyArg_ParseTuple (args, "s", &input))
    return NULL;

  gdbpy_ref<> py_argv (PyList_New (0));
  if (py_argv == NULL)
    return NULL;

  /* buildargv uses NULL to represent an empty argument list, but we can't use
     that in Python.  Instead, if ARGS is "" then return an empty list.
     This undoes the NULL -> "" conversion that cmdpy_function does.  */

  if (*input != '\0')
    {
      gdb_argv c_argv (input);

      for (char *arg : c_argv)
	{
	  gdbpy_ref<> argp (PyUnicode_FromString (arg));

	  if (argp == NULL || PyList_Append (py_argv.get (), argp.get ()) < 0)
	    return NULL;
	}
    }

  return py_argv.release ();
}
