/*
 * UPIWIN - Micro Pi Windowing Framework Kernel
 * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
 *
 * 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 2 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *-------------------------------------------------------------------------
 */
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "ep_util.h"
#include "log.h"

void Epython_log_object(int level, const char *label, PyObject *object)
{
  BOOL traced = FALSE;
  PyObject *repr;
  PCSTR pstr;

  repr = PyObject_Repr(object);
  if (repr)
  {
    ASSERT(PyUnicode_Check(repr));
    pstr = PyUnicode_AsUTF8(repr);
    Log(level, "object %s: %s", label, pstr);
    traced = TRUE;
    Py_DECREF(repr);
  }

  if (!traced)
    Log(level, "object %s: could not be logged (memory error)", label);
}

HRESULT Epython_trace_exception(void)
{
  HRESULT hr = E_FAIL;

  PyObject *type, *value, *traceback;
  PyErr_Fetch(&type, &value, &traceback);
  if (!type)
    return S_OK;

  Epython_log_object(LERROR, "exception type", type);
  Epython_log_object(LERROR, "exception value", value);
  Epython_log_object(LERROR, "exception traceback", value);

  Py_DECREF(type);
  Py_DECREF(value);
  Py_DECREF(traceback);
  return hr;
}

HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table)
{
  HRESULT hr = S_OK;
  int i = 0, rc;

  while (const_table[i].name)
  {
    switch (const_table[i].regtype)
    {
      case 'i':
        rc = PyModule_AddIntConstant(module, const_table[i].name, const_table[i].value.ival);
        break;
      case 's':
        rc = PyModule_AddStringConstant(module, const_table[i].name, const_table[i].value.sval);
        break;
      default:
        Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype);
        return E_UNEXPECTED;
    }
    if (rc)
    {
      Log(LERROR, "Failed to register constant %s", const_table[i].name);
      hr = E_FAIL;
      break;
    }
    ++i;
  }

  return hr;
}
