/* Python interface to MI commands

   Copyright (C) 2023-2024 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 "python-internal.h"
#include "py-uiout.h"
#include "utils.h"
#include "ui.h"
#include "interps.h"
#include "target.h"
#include "mi/mi-parse.h"
#include "mi/mi-console.h"
#include "mi/mi-interp.h"

void
py_ui_out::add_field (const char *name, const gdbpy_ref<> &obj)
{
  if (obj == nullptr)
    {
      m_error.emplace ();
      return;
    }

  object_desc &desc = current ();
  if (desc.type == ui_out_type_list)
    {
      if (PyList_Append (desc.obj.get (), obj.get ()) < 0)
	m_error.emplace ();
    }
  else
    {
      if (PyDict_SetItemString (desc.obj.get (), name, obj.get ()) < 0)
	m_error.emplace ();
    }
}

void
py_ui_out::do_begin (ui_out_type type, const char *id)
{
  if (m_error.has_value ())
    return;

  gdbpy_ref<> new_obj (type == ui_out_type_list
		       ? PyList_New (0)
		       : PyDict_New ());
  if (new_obj == nullptr)
    {
      m_error.emplace ();
      return;
    }

  object_desc new_desc;
  if (id != nullptr)
    new_desc.field_name = id;
  new_desc.obj = std::move (new_obj);
  new_desc.type = type;

  m_objects.push_back (std::move (new_desc));
}

void
py_ui_out::do_end (ui_out_type type)
{
  if (m_error.has_value ())
    return;

  object_desc new_obj = std::move (current ());
  m_objects.pop_back ();
  add_field (new_obj.field_name.c_str (), new_obj.obj);
}

void
py_ui_out::do_field_signed (int fldno, int width, ui_align align,
			    const char *fldname, LONGEST value,
			    const ui_file_style &style)
{
  if (m_error.has_value ())
    return;

  gdbpy_ref<> val = gdb_py_object_from_longest (value);
  add_field (fldname, val);
}

void
py_ui_out::do_field_unsigned (int fldno, int width, ui_align align,
			    const char *fldname, ULONGEST value)
{
  if (m_error.has_value ())
    return;

  gdbpy_ref<> val = gdb_py_object_from_ulongest (value);
  add_field (fldname, val);
}

void
py_ui_out::do_field_string (int fldno, int width, ui_align align,
			    const char *fldname, const char *string,
			    const ui_file_style &style)
{
  if (m_error.has_value ())
    return;

  gdbpy_ref<> val = host_string_to_python_string (string);
  add_field (fldname, val);
}

void
py_ui_out::do_field_fmt (int fldno, int width, ui_align align,
			 const char *fldname, const ui_file_style &style,
			 const char *format, va_list args)
{
  if (m_error.has_value ())
    return;

  std::string str = string_vprintf (format, args);
  do_field_string (fldno, width, align, fldname, str.c_str (), style);
}

/* Implementation of the gdb.execute_mi command.  */

PyObject *
gdbpy_execute_mi_command (PyObject *self, PyObject *args, PyObject *kw)
{
  gdb::unique_xmalloc_ptr<char> mi_command;
  std::vector<gdb::unique_xmalloc_ptr<char>> arg_strings;

  Py_ssize_t n_args = PyTuple_Size (args);
  if (n_args < 0)
    return nullptr;

  for (Py_ssize_t i = 0; i < n_args; ++i)
    {
      /* Note this returns a borrowed reference.  */
      PyObject *arg = PyTuple_GetItem (args, i);
      if (arg == nullptr)
	return nullptr;
      gdb::unique_xmalloc_ptr<char> str = python_string_to_host_string (arg);
      if (str == nullptr)
	return nullptr;
      if (i == 0)
	mi_command = std::move (str);
      else
	arg_strings.push_back (std::move (str));
    }

  py_ui_out uiout;

  try
    {
      scoped_restore save_uiout = make_scoped_restore (&current_uiout, &uiout);
      auto parser = std::make_unique<mi_parse> (std::move (mi_command),
						std::move (arg_strings));
      mi_execute_command (parser.get ());
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return uiout.result ().release ();
}

/* 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
    {
      if (PyLong_Check (result))
	{
	  int overflow = 0;
	  gdb_py_longest val = gdb_py_long_as_long_and_overflow (result,
								 &overflow);
	  if (PyErr_Occurred () != nullptr)
	    gdbpy_handle_exception ();
	  if (overflow == 0)
	    {
	      uiout->field_signed (field_name, val);
	      return;
	    }
	  /* Fall through to the string case on overflow.  */
	}

      gdb::unique_xmalloc_ptr<char> string (gdbpy_obj_to_string (result));
      if (string == nullptr)
	gdbpy_handle_exception ();
      uiout->field_string (field_name, string.get ());
    }
}

/* See python-internal.h.  */

void
serialize_mi_results (PyObject *results)
{
  gdb_assert (PyDict_Check (results));

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

/* See python-internal.h.  */

PyObject *
gdbpy_notify_mi (PyObject *self, PyObject *args, PyObject *kwargs)
{
  static const char *keywords[] = { "name", "data", nullptr };
  char *name = nullptr;
  PyObject *data = Py_None;

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "s|O", keywords,
					&name, &data))
    return nullptr;

  /* Validate notification name.  */
  const int name_len = strlen (name);
  if (name_len == 0)
    {
      PyErr_SetString (PyExc_ValueError, _("MI notification name is empty."));
      return nullptr;
    }
  for (int i = 0; i < name_len; i++)
    {
      if (!isalnum (name[i]) && name[i] != '-')
	{
	  PyErr_Format
	    (PyExc_ValueError,
	     _("MI notification name contains invalid character: %c."),
	     name[i]);
	  return nullptr;
	}
    }

  /* Validate additional data.  */
  if (!(data == Py_None || PyDict_Check (data)))
    {
      PyErr_Format
	(PyExc_ValueError,
	 _("MI notification data must be either None or a dictionary, not %s"),
	 Py_TYPE (data)->tp_name);
      return nullptr;
    }

  SWITCH_THRU_ALL_UIS ()
    {
      struct mi_interp *mi = as_mi_interp (top_level_interpreter ());

      if (mi == nullptr)
	continue;

      target_terminal::scoped_restore_terminal_state term_state;
      target_terminal::ours_for_output ();

      gdb_printf (mi->event_channel, "%s", name);
      if (data != Py_None)
	{
	  ui_out *mi_uiout = mi->interp_ui_out ();
	  ui_out_redirect_pop redir (mi_uiout, mi->event_channel);
	  scoped_restore restore_uiout
	    = make_scoped_restore (&current_uiout, mi_uiout);

	  serialize_mi_results (data);
	}
      gdb_flush (mi->event_channel);
    }

  Py_RETURN_NONE;
}
