#include "parts.h"

static PyObject *
err_set_raised(PyObject *self, PyObject *exc)
{
    Py_INCREF(exc);
    PyErr_SetRaisedException(exc);
    assert(PyErr_Occurred());
    return NULL;
}

static PyObject *
err_restore(PyObject *self, PyObject *args) {
    PyObject *type = NULL, *value = NULL, *traceback = NULL;
    switch(PyTuple_Size(args)) {
        case 3:
            traceback = PyTuple_GetItem(args, 2);
            Py_INCREF(traceback);
            /* fall through */
        case 2:
            value = PyTuple_GetItem(args, 1);
            Py_INCREF(value);
            /* fall through */
        case 1:
            type = PyTuple_GetItem(args, 0);
            Py_INCREF(type);
            break;
        default:
            PyErr_SetString(PyExc_TypeError,
                        "wrong number of arguments");
            return NULL;
    }
    PyErr_Restore(type, value, traceback);
    assert(PyErr_Occurred());
    return NULL;
}

/* To test the format of exceptions as printed out. */
static PyObject *
exception_print(PyObject *self, PyObject *args)
{
    PyObject *value;
    PyObject *tb = NULL;

    if (!PyArg_ParseTuple(args, "O:exception_print", &value)) {
        return NULL;
    }

    if (PyExceptionInstance_Check(value)) {
        tb = PyException_GetTraceback(value);
    }

    PyErr_Display((PyObject *) Py_TYPE(value), value, tb);
    Py_XDECREF(tb);

    Py_RETURN_NONE;
}

/* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException).
   Run via Lib/test/test_exceptions.py */
static PyObject *
make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs)
{
    const char *name;
    const char *doc = NULL;
    PyObject *base = NULL;
    PyObject *dict = NULL;

    static char *kwlist[] = {"name", "doc", "base", "dict", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "s|sOO:make_exception_with_doc", kwlist,
                                     &name, &doc, &base, &dict))
    {
        return NULL;
    }

    return PyErr_NewExceptionWithDoc(name, doc, base, dict);
}

static PyObject *
raise_exception(PyObject *self, PyObject *args)
{
    PyObject *exc;
    int num_args;

    if (!PyArg_ParseTuple(args, "Oi:raise_exception", &exc, &num_args)) {
        return NULL;
    }

    PyObject *exc_args = PyTuple_New(num_args);
    if (exc_args == NULL) {
        return NULL;
    }
    for (int i = 0; i < num_args; ++i) {
        PyObject *v = PyLong_FromLong(i);
        if (v == NULL) {
            Py_DECREF(exc_args);
            return NULL;
        }
        PyTuple_SET_ITEM(exc_args, i, v);
    }
    PyErr_SetObject(exc, exc_args);
    Py_DECREF(exc_args);
    return NULL;
}

/* reliably raise a MemoryError */
static PyObject *
raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored))
{
    return PyErr_NoMemory();
}

static PyObject *
test_fatal_error(PyObject *self, PyObject *args)
{
    char *message;
    int release_gil = 0;
    if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil)) {
        return NULL;
    }
    if (release_gil) {
        Py_BEGIN_ALLOW_THREADS
        Py_FatalError(message);
        Py_END_ALLOW_THREADS
    }
    else {
        Py_FatalError(message);
    }
    // Py_FatalError() does not return, but exits the process.
    Py_RETURN_NONE;
}

static PyObject *
test_set_exc_info(PyObject *self, PyObject *args)
{
    PyObject *new_type, *new_value, *new_tb;
    PyObject *type, *value, *tb;
    if (!PyArg_ParseTuple(args, "OOO:test_set_exc_info",
                          &new_type, &new_value, &new_tb))
    {
        return NULL;
    }

    PyErr_GetExcInfo(&type, &value, &tb);

    Py_INCREF(new_type);
    Py_INCREF(new_value);
    Py_INCREF(new_tb);
    PyErr_SetExcInfo(new_type, new_value, new_tb);

    PyObject *orig_exc = PyTuple_Pack(3,
            type  ? type  : Py_None,
            value ? value : Py_None,
            tb    ? tb    : Py_None);
    Py_XDECREF(type);
    Py_XDECREF(value);
    Py_XDECREF(tb);
    return orig_exc;
}

static PyObject *
test_set_exception(PyObject *self, PyObject *new_exc)
{
    PyObject *exc = PyErr_GetHandledException();
    assert(PyExceptionInstance_Check(exc) || exc == NULL);

    PyErr_SetHandledException(new_exc);
    return exc;
}

static PyObject *
test_write_unraisable_exc(PyObject *self, PyObject *args)
{
    PyObject *exc, *err_msg, *obj;
    if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) {
        return NULL;
    }

    const char *err_msg_utf8;
    if (err_msg != Py_None) {
        err_msg_utf8 = PyUnicode_AsUTF8(err_msg);
        if (err_msg_utf8 == NULL) {
            return NULL;
        }
    }
    else {
        err_msg_utf8 = NULL;
    }

    PyErr_SetObject((PyObject *)Py_TYPE(exc), exc);
    _PyErr_WriteUnraisableMsg(err_msg_utf8, obj);
    Py_RETURN_NONE;
}

/* To test the format of tracebacks as printed out. */
static PyObject *
traceback_print(PyObject *self, PyObject *args)
{
    PyObject *file;
    PyObject *traceback;

    if (!PyArg_ParseTuple(args, "OO:traceback_print",
                            &traceback, &file))
    {
        return NULL;
    }

    if (PyTraceBack_Print(traceback, file) < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}


/*
 * Define the PyRecurdingInfinitelyError_Type
 */

static PyTypeObject PyRecursingInfinitelyError_Type;

static int
recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;

    /* Instantiating this exception starts infinite recursion. */
    Py_INCREF(type);
    PyErr_SetObject(type, NULL);
    return -1;
}

static PyTypeObject PyRecursingInfinitelyError_Type = {
    .tp_name = "RecursingInfinitelyError",
    .tp_basicsize = sizeof(PyBaseExceptionObject),
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
    .tp_doc = PyDoc_STR("Instantiating this exception starts infinite recursion."),
    .tp_init = (initproc)recurse_infinitely_error_init,
};

static PyMethodDef test_methods[] = {
    {"err_restore",             err_restore,                     METH_VARARGS},
    {"err_set_raised",          err_set_raised,                  METH_O},
    {"exception_print",         exception_print,                 METH_VARARGS},
    {"fatal_error",             test_fatal_error,                METH_VARARGS,
     PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
    {"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc),
     METH_VARARGS | METH_KEYWORDS},
    {"raise_exception",         raise_exception,                 METH_VARARGS},
    {"raise_memoryerror",       raise_memoryerror,               METH_NOARGS},
    {"set_exc_info",            test_set_exc_info,               METH_VARARGS},
    {"set_exception",           test_set_exception,              METH_O},
    {"traceback_print",         traceback_print,                 METH_VARARGS},
    {"write_unraisable_exc",    test_write_unraisable_exc,       METH_VARARGS},
    {NULL},
};

int
_PyTestCapi_Init_Exceptions(PyObject *mod)
{
    PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
    if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(mod, "RecursingInfinitelyError",
                              (PyObject *)&PyRecursingInfinitelyError_Type) < 0)
    {
        return -1;
    }

    if (PyModule_AddFunctions(mod, test_methods) < 0) {
        return -1;
    }

    return 0;
}
