/* Implementation helper: a struct that looks like a tuple.  See timemodule
   and posixmodule for example uses. */

#include "Python.h"
#include "structmember.h"
#include "structseq.h"

static char visible_length_key[] = "n_sequence_fields";
static char real_length_key[] = "n_fields";
static char unnamed_fields_key[] = "n_unnamed_fields";

/* Fields with this name have only a field index, not a field name.
   They are only allowed for indices < n_visible_fields. */
char *PyStructSequence_UnnamedField = "unnamed field";

#define VISIBLE_SIZE(op) Py_SIZE(op)
#define VISIBLE_SIZE_TP(tp) PyLong_AsLong( \
                      PyDict_GetItemString((tp)->tp_dict, visible_length_key))

#define REAL_SIZE_TP(tp) PyLong_AsLong( \
                      PyDict_GetItemString((tp)->tp_dict, real_length_key))
#define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))

#define UNNAMED_FIELDS_TP(tp) PyLong_AsLong( \
                      PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))


PyObject *
PyStructSequence_New(PyTypeObject *type)
{
    PyStructSequence *obj;

    obj = PyObject_New(PyStructSequence, type);
    if (obj == NULL)
        return NULL;
    Py_SIZE(obj) = VISIBLE_SIZE_TP(type);

    return (PyObject*) obj;
}

static void
structseq_dealloc(PyStructSequence *obj)
{
    Py_ssize_t i, size;

    size = REAL_SIZE(obj);
    for (i = 0; i < size; ++i) {
        Py_XDECREF(obj->ob_item[i]);
    }
    PyObject_Del(obj);
}

static Py_ssize_t
structseq_length(PyStructSequence *obj)
{
    return VISIBLE_SIZE(obj);
}

static PyObject*
structseq_item(PyStructSequence *obj, Py_ssize_t i)
{
    if (i < 0 || i >= VISIBLE_SIZE(obj)) {
        PyErr_SetString(PyExc_IndexError, "tuple index out of range");
        return NULL;
    }
    Py_INCREF(obj->ob_item[i]);
    return obj->ob_item[i];
}

static PyObject*
structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high)
{
    PyTupleObject *np;
    Py_ssize_t i;

    if (low < 0)
        low = 0;
    if (high > VISIBLE_SIZE(obj))
        high = VISIBLE_SIZE(obj);
    if (high < low)
        high = low;
    np = (PyTupleObject *)PyTuple_New(high-low);
    if (np == NULL)
        return NULL;
    for(i = low; i < high; ++i) {
        PyObject *v = obj->ob_item[i];
        Py_INCREF(v);
        PyTuple_SET_ITEM(np, i-low, v);
    }
    return (PyObject *) np;
}

static PyObject *
structseq_subscript(PyStructSequence *self, PyObject *item)
{
    if (PyIndex_Check(item)) {
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
        if (i == -1 && PyErr_Occurred())
            return NULL;

        if (i < 0)
            i += VISIBLE_SIZE(self);

        if (i < 0 || i >= VISIBLE_SIZE(self)) {
            PyErr_SetString(PyExc_IndexError,
                "tuple index out of range");
            return NULL;
        }
        Py_INCREF(self->ob_item[i]);
        return self->ob_item[i];
    }
    else if (PySlice_Check(item)) {
        Py_ssize_t start, stop, step, slicelen, cur, i;
        PyObject *result;

        if (PySlice_GetIndicesEx((PySliceObject *)item,
                                 VISIBLE_SIZE(self), &start, &stop,
                                 &step, &slicelen) < 0) {
            return NULL;
        }
        if (slicelen <= 0)
            return PyTuple_New(0);
        result = PyTuple_New(slicelen);
        if (result == NULL)
            return NULL;
        for (cur = start, i = 0; i < slicelen;
             cur += step, i++) {
            PyObject *v = self->ob_item[cur];
            Py_INCREF(v);
            PyTuple_SET_ITEM(result, i, v);
        }
        return result;
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "structseq index must be integer");
        return NULL;
    }
}

static PyObject *
structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *arg = NULL;
    PyObject *dict = NULL;
    PyObject *ob;
    PyStructSequence *res = NULL;
    Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
    static char *kwlist[] = {"sequence", "dict", 0};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq",
                                     kwlist, &arg, &dict))
        return NULL;

    arg = PySequence_Fast(arg, "constructor requires a sequence");

    if (!arg) {
        return NULL;
    }

    if (dict && !PyDict_Check(dict)) {
        PyErr_Format(PyExc_TypeError,
                     "%.500s() takes a dict as second arg, if any",
                     type->tp_name);
        Py_DECREF(arg);
        return NULL;
    }

    len = PySequence_Fast_GET_SIZE(arg);
    min_len = VISIBLE_SIZE_TP(type);
    max_len = REAL_SIZE_TP(type);
    n_unnamed_fields = UNNAMED_FIELDS_TP(type);

    if (min_len != max_len) {
        if (len < min_len) {
            PyErr_Format(PyExc_TypeError,
           "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
                                 type->tp_name, min_len, len);
                    Py_DECREF(arg);
                    return NULL;
        }

        if (len > max_len) {
            PyErr_Format(PyExc_TypeError,
           "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
                                 type->tp_name, max_len, len);
                    Py_DECREF(arg);
                    return NULL;
        }
    }
    else {
        if (len != min_len) {
            PyErr_Format(PyExc_TypeError,
           "%.500s() takes a %zd-sequence (%zd-sequence given)",
                                 type->tp_name, min_len, len);
                    Py_DECREF(arg);
                    return NULL;
        }
    }

    res = (PyStructSequence*) PyStructSequence_New(type);
    if (res == NULL) {
        return NULL;
    }
    for (i = 0; i < len; ++i) {
        PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
        Py_INCREF(v);
        res->ob_item[i] = v;
    }
    for (; i < max_len; ++i) {
        if (dict && (ob = PyDict_GetItemString(
            dict, type->tp_members[i-n_unnamed_fields].name))) {
        }
        else {
            ob = Py_None;
        }
        Py_INCREF(ob);
        res->ob_item[i] = ob;
    }

    Py_DECREF(arg);
    return (PyObject*) res;
}

static PyObject *
make_tuple(PyStructSequence *obj)
{
    return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
}

static PyObject *
structseq_repr(PyStructSequence *obj)
{
    /* buffer and type size were chosen well considered. */
#define REPR_BUFFER_SIZE 512
#define TYPE_MAXSIZE 100

    PyObject *tup;
    PyTypeObject *typ = Py_TYPE(obj);
    int i, removelast = 0;
    Py_ssize_t len;
    char buf[REPR_BUFFER_SIZE];
    char *endofbuf, *pbuf = buf;

    /* pointer to end of writeable buffer; safes space for "...)\0" */
    endofbuf= &buf[REPR_BUFFER_SIZE-5];

    if ((tup = make_tuple(obj)) == NULL) {
        return NULL;
    }

    /* "typename(", limited to  TYPE_MAXSIZE */
    len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
                            strlen(typ->tp_name);
    strncpy(pbuf, typ->tp_name, len);
    pbuf += len;
    *pbuf++ = '(';

    for (i=0; i < VISIBLE_SIZE(obj); i++) {
        PyObject *val, *repr;
        char *cname, *crepr;

        cname = typ->tp_members[i].name;

        val = PyTuple_GetItem(tup, i);
        if (cname == NULL || val == NULL) {
            return NULL;
        }
        repr = PyObject_Repr(val);
        if (repr == NULL) {
            Py_DECREF(tup);
            return NULL;
        }
        crepr = _PyUnicode_AsString(repr);
        if (crepr == NULL) {
            Py_DECREF(tup);
            Py_DECREF(repr);
            return NULL;
        }

        /* + 3: keep space for "=" and ", " */
        len = strlen(cname) + strlen(crepr) + 3;
        if ((pbuf+len) <= endofbuf) {
            strcpy(pbuf, cname);
            pbuf += strlen(cname);
            *pbuf++ = '=';
            strcpy(pbuf, crepr);
            pbuf += strlen(crepr);
            *pbuf++ = ',';
            *pbuf++ = ' ';
            removelast = 1;
            Py_DECREF(repr);
        }
        else {
            strcpy(pbuf, "...");
            pbuf += 3;
            removelast = 0;
            Py_DECREF(repr);
            break;
        }
    }
    Py_DECREF(tup);
    if (removelast) {
        /* overwrite last ", " */
        pbuf-=2;
    }
    *pbuf++ = ')';
    *pbuf = '\0';

    return PyUnicode_FromString(buf);
}

static PyObject *
structseq_concat(PyStructSequence *obj, PyObject *b)
{
    PyObject *tup, *result;
    tup = make_tuple(obj);
    result = PySequence_Concat(tup, b);
    Py_DECREF(tup);
    return result;
}

static PyObject *
structseq_repeat(PyStructSequence *obj, Py_ssize_t n)
{
    PyObject *tup, *result;
    tup = make_tuple(obj);
    result = PySequence_Repeat(tup, n);
    Py_DECREF(tup);
    return result;
}

static int
structseq_contains(PyStructSequence *obj, PyObject *o)
{
    PyObject *tup;
    int result;
    tup = make_tuple(obj);
    if (!tup)
        return -1;
    result = PySequence_Contains(tup, o);
    Py_DECREF(tup);
    return result;
}

static long
structseq_hash(PyObject *obj)
{
    PyObject *tup;
    long result;
    tup = make_tuple((PyStructSequence*) obj);
    if (!tup)
        return -1;
    result = PyObject_Hash(tup);
    Py_DECREF(tup);
    return result;
}

static PyObject *
structseq_richcompare(PyObject *obj, PyObject *o2, int op)
{
    PyObject *tup, *result;
    tup = make_tuple((PyStructSequence*) obj);
    result = PyObject_RichCompare(tup, o2, op);
    Py_DECREF(tup);
    return result;
}

static PyObject *
structseq_reduce(PyStructSequence* self)
{
    PyObject* tup;
    PyObject* dict;
    PyObject* result;
    Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
    int i;

    n_fields = REAL_SIZE(self);
    n_visible_fields = VISIBLE_SIZE(self);
    n_unnamed_fields = UNNAMED_FIELDS(self);
    tup = PyTuple_New(n_visible_fields);
    if (!tup) {
        return NULL;
    }

    dict = PyDict_New();
    if (!dict) {
        Py_DECREF(tup);
        return NULL;
    }

    for (i = 0; i < n_visible_fields; i++) {
        Py_INCREF(self->ob_item[i]);
        PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
    }

    for (; i < n_fields; i++) {
        char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
        PyDict_SetItemString(dict, n,
                             self->ob_item[i]);
    }

    result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);

    Py_DECREF(tup);
    Py_DECREF(dict);

    return result;
}

static PySequenceMethods structseq_as_sequence = {
    (lenfunc)structseq_length,
    (binaryfunc)structseq_concat,           /* sq_concat */
    (ssizeargfunc)structseq_repeat,         /* sq_repeat */
    (ssizeargfunc)structseq_item,               /* sq_item */
    0,                                          /* sq_slice */
    0,                                          /* sq_ass_item */
    0,                                          /* sq_ass_slice */
    (objobjproc)structseq_contains,             /* sq_contains */
};

static PyMappingMethods structseq_as_mapping = {
    (lenfunc)structseq_length,
    (binaryfunc)structseq_subscript,
};

static PyMethodDef structseq_methods[] = {
    {"__reduce__", (PyCFunction)structseq_reduce,
     METH_NOARGS, NULL},
    {NULL, NULL}
};

static PyTypeObject _struct_sequence_template = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    NULL,                                       /* tp_name */
    0,                                          /* tp_basicsize */
    0,                                          /* tp_itemsize */
    (destructor)structseq_dealloc,              /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    (reprfunc)structseq_repr,                   /* tp_repr */
    0,                                          /* tp_as_number */
    &structseq_as_sequence,                     /* tp_as_sequence */
    &structseq_as_mapping,                      /* tp_as_mapping */
    structseq_hash,                             /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
    NULL,                                       /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    structseq_richcompare,                      /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    structseq_methods,                          /* tp_methods */
    NULL,                                       /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    structseq_new,                              /* tp_new */
};

void
PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
{
    PyObject *dict;
    PyMemberDef* members;
    int n_members, n_unnamed_members, i, k;

#ifdef Py_TRACE_REFS
    /* if the type object was chained, unchain it first
       before overwriting its storage */
    if (type->ob_base.ob_base._ob_next) {
        _Py_ForgetReference((PyObject*)type);
    }
#endif

    n_unnamed_members = 0;
    for (i = 0; desc->fields[i].name != NULL; ++i)
        if (desc->fields[i].name == PyStructSequence_UnnamedField)
            n_unnamed_members++;
    n_members = i;

    memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
    type->tp_name = desc->name;
    type->tp_doc = desc->doc;
    type->tp_basicsize = sizeof(PyStructSequence)+
        sizeof(PyObject*)*(n_members-1);
    type->tp_itemsize = 0;

    members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
    if (members == NULL)
        return;

    for (i = k = 0; i < n_members; ++i) {
        if (desc->fields[i].name == PyStructSequence_UnnamedField)
            continue;
        members[k].name = desc->fields[i].name;
        members[k].type = T_OBJECT;
        members[k].offset = offsetof(PyStructSequence, ob_item)
          + i * sizeof(PyObject*);
        members[k].flags = READONLY;
        members[k].doc = desc->fields[i].doc;
        k++;
    }
    members[k].name = NULL;

    type->tp_members = members;

    if (PyType_Ready(type) < 0)
        return;
    Py_INCREF(type);

    dict = type->tp_dict;
#define SET_DICT_FROM_INT(key, value)                           \
    do {                                                        \
        PyObject *v = PyLong_FromLong((long) value);            \
        if (v != NULL) {                                        \
            PyDict_SetItemString(dict, key, v);                 \
            Py_DECREF(v);                                       \
        }                                                       \
    } while (0)

    SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence);
    SET_DICT_FROM_INT(real_length_key, n_members);
    SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
}
