/* Python interface to ui_file_style::color objects.

   Copyright (C) 2008-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-color.h"
#include "cli/cli-decode.h"

/* Colorspace constants and their values.  */
static struct {
  const char *name;
  color_space value;
} colorspace_constants[] =
{
  { "COLORSPACE_MONOCHROME", color_space::MONOCHROME },
  { "COLORSPACE_ANSI_8COLOR", color_space::ANSI_8COLOR },
  { "COLORSPACE_AIXTERM_16COLOR", color_space::AIXTERM_16COLOR },
  { "COLORSPACE_XTERM_256COLOR", color_space::XTERM_256COLOR },
  { "COLORSPACE_RGB_24BIT", color_space::RGB_24BIT },
};

/* A color.  */
struct colorpy_object
{
  PyObject_HEAD

  /* Underlying value.  */
  ui_file_style::color color;
};

extern PyTypeObject colorpy_object_type;

/* See py-color.h.  */
gdbpy_ref<>
create_color_object (const ui_file_style::color &color)
{
  gdbpy_ref<colorpy_object> color_obj (PyObject_New (colorpy_object,
						     &colorpy_object_type));

  if (color_obj == nullptr)
    return nullptr;

  color_obj->color = color;
  return gdbpy_ref<> ((PyObject *) color_obj.release ());
}

/* See py-color.h.  */
bool
gdbpy_is_color (PyObject *obj)
{
  return PyObject_IsInstance (obj, (PyObject *) &colorpy_object_type);
}

/* See py-color.h.  */
const ui_file_style::color &
gdbpy_get_color (PyObject *obj)
{
  gdb_assert (gdbpy_is_color (obj));
  colorpy_object *self = (colorpy_object *) obj;
  return self->color;
}

/* Get an attribute.  */
static PyObject *
get_attr (PyObject *obj, PyObject *attr_name)
{
  if (! PyUnicode_Check (attr_name))
    return PyObject_GenericGetAttr (obj, attr_name);

  colorpy_object *self = (colorpy_object *) obj;
  const ui_file_style::color &color = self->color;

  if (! PyUnicode_CompareWithASCIIString (attr_name, "colorspace"))
    {
      int value = static_cast<int> (color.colorspace ());
      return gdb_py_object_from_longest (value).release ();
    }

  if (! PyUnicode_CompareWithASCIIString (attr_name, "is_none"))
    return PyBool_FromLong (color.is_none ());

  if (! PyUnicode_CompareWithASCIIString (attr_name, "is_indexed"))
    return PyBool_FromLong (color.is_indexed ());

  if (! PyUnicode_CompareWithASCIIString (attr_name, "is_direct"))
    return PyBool_FromLong (color.is_direct ());

  if (color.is_indexed ()
      && ! PyUnicode_CompareWithASCIIString (attr_name, "index"))
    return gdb_py_object_from_longest (color.get_value ()).release ();

  if (color.is_direct ()
      && ! PyUnicode_CompareWithASCIIString (attr_name, "components"))
    {
      uint8_t rgb[3];
      color.get_rgb (rgb);

      gdbpy_ref<> rgb_objects[3];
      for (int i = 0; i < 3; ++i)
	{
	  rgb_objects[i] = gdb_py_object_from_ulongest (rgb[i]);
	  if (rgb_objects[i] == nullptr)
	    return nullptr;
	}

      PyObject *comp = PyTuple_New (3);
      if (comp == nullptr)
	return nullptr;

      for (int i = 0; i < 3; ++i)
	PyTuple_SET_ITEM (comp, i, rgb_objects[i].release ());

      return comp;
    }

  return PyObject_GenericGetAttr (obj, attr_name);
}

/* Implementation of Color.escape_sequence (self, is_fg) -> str.  */

static PyObject *
colorpy_escape_sequence (PyObject *self, PyObject *is_fg_obj)
{
  if (!gdbpy_is_color (self))
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Object is not gdb.Color."));
      return nullptr;
    }

  if (! PyBool_Check (is_fg_obj))
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("A boolean argument is required."));
      return nullptr;
    }

  bool is_fg = is_fg_obj == Py_True;
  std::string s = gdbpy_get_color (self).to_ansi (is_fg);

  return host_string_to_python_string (s.c_str ()).release ();
}

/* Object initializer; fills color with value.

   Use: __init__(VALUE = None, COLORSPACE = None)

   VALUE is a string, integer, RGB-tuple or None.

   COLORSPACE is the color space index.

   Returns -1 on error, with a python exception set.  */

static int
colorpy_init (PyObject *self, PyObject *args, PyObject *kwds)
{
  colorpy_object *obj = (colorpy_object *) self;
  PyObject *value_obj = nullptr;
  PyObject *colorspace_obj = nullptr;
  color_space colorspace = color_space::MONOCHROME;

  if (! PyArg_ParseTuple (args, "|OO", &value_obj, &colorspace_obj))
    return -1;

  try
    {
      if (colorspace_obj)
	{
	  if (PyLong_Check (colorspace_obj))
	    {
	      long colorspace_id = -1;
	      if (! gdb_py_int_as_long (colorspace_obj, &colorspace_id))
		return -1;
	      if (!color_space_safe_cast (&colorspace, colorspace_id))
		error (_("colorspace %ld is out of range."), colorspace_id);
	    }
	  else if (colorspace_obj == Py_None)
	    colorspace_obj = nullptr;
	  else
	    error (_("colorspace must be None or integer"));
	}

      if (value_obj == nullptr || value_obj == Py_None)
	  obj->color = ui_file_style::color (colorspace, -1);
      else if (PyLong_Check (value_obj))
	{
	  long value = -1;
	  if (! gdb_py_int_as_long (value_obj, &value))
	    return -1;
	  if (value < 0 || value > INT_MAX)
	    error (_("value %ld is out of range."), value);
	  if (colorspace_obj)
	    obj->color = ui_file_style::color (colorspace, value);
	  else
	    obj->color = ui_file_style::color (value);
	}
      else if (PyTuple_Check (value_obj))
	{
	  if (colorspace_obj == nullptr || colorspace != color_space::RGB_24BIT)
	    error (_("colorspace must be gdb.COLORSPACE_RGB_24BIT with "
		   "value of tuple type."));
	  Py_ssize_t tuple_size = PyTuple_Size (value_obj);
	  if (tuple_size < 0)
	    return -1;
	  if (tuple_size != 3)
	    error (_("Tuple value with RGB must be of size 3."));
	  uint8_t rgb[3];
	  for (int i = 0; i < 3; ++i)
	    {
	      PyObject *item = PyTuple_GetItem (value_obj, i);
	      if (!PyLong_Check (item))
		error (_("Item %d of an RGB tuple must be integer."), i);
	      long item_value = -1;
	      if (!gdb_py_int_as_long (item, &item_value))
		return -1;
	      if (item_value < 0 || item_value > UINT8_MAX)
		error (_("RGB item %ld is out of byte range."), item_value);
	      rgb[i] = static_cast<uint8_t> (item_value);
	    }

	  obj->color = ui_file_style::color (rgb[0], rgb[1], rgb[2]);
	}
      else if (PyUnicode_Check (value_obj))
	{
	  gdb::unique_xmalloc_ptr<char>
	    str (python_string_to_host_string (value_obj));
	  if (str == nullptr)
	    return -1;
	  obj->color = parse_var_color (str.get());

	  if (colorspace_obj != nullptr
	      && colorspace != obj->color.colorspace ())
	    error (_("colorspace doesn't match to the value."));
	}
      else
	error (_("value must be one of None, integer, tuple or str."));
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (-1, except);
    }

  Py_INCREF (self);
  return 0;
}

static PyObject *
colorpy_str (PyObject *self)
{
  colorpy_object *obj = reinterpret_cast<colorpy_object *> (self);

  return PyUnicode_FromString (obj->color.to_string ().c_str ());
}

/* Initialize the 'color' module.  */
static int
gdbpy_initialize_color (void)
{
  for (auto & pair : colorspace_constants)
      if (PyModule_AddIntConstant (gdb_module, pair.name,
				   static_cast<long> (pair.value)) < 0)
	return -1;

  colorpy_object_type.tp_new = PyType_GenericNew;
  return gdbpy_type_ready (&colorpy_object_type, gdb_module);
}

/* Color methods.  */

static PyMethodDef color_methods[] =
{
  { "escape_sequence", colorpy_escape_sequence, METH_O,
    "escape_sequence (is_foreground) -> str.\n\
Return the ANSI escape sequence for this color.\n\
IS_FOREGROUND indicates whether this is a foreground or background color."},
  {nullptr}
};

PyTypeObject colorpy_object_type =
{
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.Color",			  /*tp_name*/
  sizeof (colorpy_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*/
  colorpy_str,			  /*tp_str*/
  get_attr,			  /*tp_getattro*/
  0,				  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
  "GDB color object",	  	  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  0,				  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  0,				  /* tp_iter */
  0,				  /* tp_iternext */
  color_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 */
  colorpy_init,			  /* tp_init */
  0,				  /* tp_alloc */
};

GDBPY_INITIALIZE_FILE (gdbpy_initialize_color);
