/* 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);
	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_compare */
	(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;
	PyDict_SetItemString(dict, visible_length_key, 
		       PyLong_FromLong((long) desc->n_in_sequence));
	PyDict_SetItemString(dict, real_length_key, 
		       PyLong_FromLong((long) n_members));
	PyDict_SetItemString(dict, unnamed_fields_key, 
		       PyLong_FromLong((long) n_unnamed_members));
}
