/* Copyright (C) 2013-2021 Free Software Foundation, Inc.

   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 "python-internal.h"
#include "varobj.h"
#include "varobj-iter.h"

/* A dynamic varobj iterator "class" for python pretty-printed
   varobjs.  This inherits struct varobj_iter.  */

struct py_varobj_iter
{
  /* The 'base class'.  */
  struct varobj_iter base;

  /* The python iterator returned by the printer's 'children' method,
     or NULL if not available.  */
  PyObject *iter;
};

/* Implementation of the 'dtor' method of pretty-printed varobj
   iterators.  */

static void
py_varobj_iter_dtor (struct varobj_iter *self)
{
  struct py_varobj_iter *dis = (struct py_varobj_iter *) self;
  gdbpy_enter_varobj enter_py (self->var);
  Py_XDECREF (dis->iter);
}

/* Implementation of the 'next' method of pretty-printed varobj
   iterators.  */

static varobj_item *
py_varobj_iter_next (struct varobj_iter *self)
{
  struct py_varobj_iter *t = (struct py_varobj_iter *) self;
  PyObject *py_v;
  varobj_item *vitem;
  const char *name = NULL;

  if (!gdb_python_initialized)
    return NULL;

  gdbpy_enter_varobj enter_py (self->var);

  gdbpy_ref<> item (PyIter_Next (t->iter));

  if (item == NULL)
    {
      /* Normal end of iteration.  */
      if (!PyErr_Occurred ())
	return NULL;

      /* If we got a memory error, just use the text as the item.  */
      if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
	{
	  gdbpy_err_fetch fetched_error;
	  gdb::unique_xmalloc_ptr<char> value_str = fetched_error.to_string ();
	  if (value_str == NULL)
	    {
	      gdbpy_print_stack ();
	      return NULL;
	    }

	  std::string name_str = string_printf ("<error at %d>",
						self->next_raw_index++);
	  item.reset (Py_BuildValue ("(ss)", name_str.c_str (),
				     value_str.get ()));
	  if (item == NULL)
	    {
	      gdbpy_print_stack ();
	      return NULL;
	    }
	}
      else
	{
	  /* Any other kind of error.  */
	  gdbpy_print_stack ();
	  return NULL;
	}
    }

  if (!PyArg_ParseTuple (item.get (), "sO", &name, &py_v))
    {
      gdbpy_print_stack ();
      error (_("Invalid item from the child list"));
    }

  vitem = new varobj_item ();
  vitem->value = convert_value_from_python (py_v);
  if (vitem->value == NULL)
    gdbpy_print_stack ();
  vitem->name = name;

  self->next_raw_index++;
  return vitem;
}

/* The 'vtable' of pretty-printed python varobj iterators.  */

static const struct varobj_iter_ops py_varobj_iter_ops =
{
  py_varobj_iter_dtor,
  py_varobj_iter_next
};

/* Constructor of pretty-printed varobj iterators.  VAR is the varobj
   whose children the iterator will be iterating over.  PYITER is the
   python iterator actually responsible for the iteration.  */

static void
py_varobj_iter_ctor (struct py_varobj_iter *self,
		     struct varobj *var, gdbpy_ref<> &&pyiter)
{
  self->base.var = var;
  self->base.ops = &py_varobj_iter_ops;
  self->base.next_raw_index = 0;
  self->iter = pyiter.release ();
}

/* Allocate and construct a pretty-printed varobj iterator.  VAR is
   the varobj whose children the iterator will be iterating over.
   PYITER is the python iterator actually responsible for the
   iteration.  */

static struct py_varobj_iter *
py_varobj_iter_new (struct varobj *var, gdbpy_ref<> &&pyiter)
{
  struct py_varobj_iter *self;

  self = XNEW (struct py_varobj_iter);
  py_varobj_iter_ctor (self, var, std::move (pyiter));
  return self;
}

/* Return a new pretty-printed varobj iterator suitable to iterate
   over VAR's children.  */

struct varobj_iter *
py_varobj_get_iterator (struct varobj *var, PyObject *printer)
{
  struct py_varobj_iter *py_iter;

  gdbpy_enter_varobj enter_py (var);

  if (!PyObject_HasAttr (printer, gdbpy_children_cst))
    return NULL;

  gdbpy_ref<> children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
						    NULL));
  if (children == NULL)
    {
      gdbpy_print_stack ();
      error (_("Null value returned for children"));
    }

  gdbpy_ref<> iter (PyObject_GetIter (children.get ()));
  if (iter == NULL)
    {
      gdbpy_print_stack ();
      error (_("Could not get children iterator"));
    }

  py_iter = py_varobj_iter_new (var, std::move (iter));

  return &py_iter->base;
}
