#include <Python.h>
#include <stdio.h>

static PyObject *base_class;

static int
base_traverse(PyObject *self, visitproc visit, void *arg)
{
    // imagine this needs to do something
    return 0;
}

static PyType_Slot base_slots[] = {
    {Py_tp_traverse, base_traverse},
    {0, 0},
};

static PyType_Spec base_spec = {
    "reproducer.Base",
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    .slots = base_slots
};

static int
subclass_traverse(PyObject *self, visitproc visit, void *arg)
{
    if (PyErr_CheckSignals()) return -1;

    // Call the superclass traverse
    PyTypeObject *base = (PyTypeObject*)base_class;
    traverseproc super_traverse = PyType_GetSlot(base, Py_tp_traverse);
    return super_traverse(self, visit, arg);
}

static PyType_Slot subclass_slots[] = {
    {Py_tp_traverse, subclass_traverse},
    {0, 0},
};

static PyType_Spec subclass_spec = {
    "reproducer.Subclass",
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
    .slots = subclass_slots
};

static int
reproducer_exec(PyObject *m)
{
    // Error handling simplified for clarity
    int result;

    if (base_class != NULL) {
        // fail gracefully in subinterpreters
        PyErr_SetString(
            PyExc_SystemError, "this module can only be loaded once");
        return -1;
    }

    base_class = PyType_FromModuleAndSpec(m, &base_spec, NULL);
    if (!base_class) return -1;

    result = PyModule_AddObject(m, "Base", base_class);
    if (result) return -1;

    PyObject *bases = PyTuple_New(1);
    result = PyTuple_SetItem(bases, 0, base_class);
    if (result) return -1;

    PyObject *subclass = PyType_FromModuleAndSpec(m, &subclass_spec, bases);
    if (!subclass) return -1;

    result = PyModule_AddObject(m, "Sub", subclass);
    if (result) return -1;

    PyObject *instance = PyObject_CallNoArgs(subclass);
    if (!instance) return -1;
    result = PyModule_AddObject(m, "instance", instance);
    if (result) return -1;

    return 0;
}

static PyModuleDef_Slot reproducer_slots[] = {
    {Py_mod_exec, reproducer_exec},
    {0, NULL}
};

static struct PyModuleDef reproducer_module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "reproducer",
    .m_slots = reproducer_slots,
};

PyMODINIT_FUNC
PyInit_reproducer(void)
{
    return PyModuleDef_Init(&reproducer_module);
}
