/**
 * jinja2._speedups
 * ~~~~~~~~~~~~~~~~
 *
 * This module implements a few functions in C for better performance.
 *
 * :copyright: 2008 by Armin Ronacher.
 * :license: BSD.
 */

#include <Python.h>


static const char *samp = "&amp;", *slt = "&lt;", *sgt = "&gt;", *sqt = "&quot;";
static Py_UNICODE *amp, *lt, *gt, *qt;
static PyObject* markup;


static int
init_constants(void)
{
	amp = ((PyUnicodeObject*)PyUnicode_DecodeASCII(samp, 5, NULL))->str;
	lt = ((PyUnicodeObject*)PyUnicode_DecodeASCII(slt, 4, NULL))->str;
	gt = ((PyUnicodeObject*)PyUnicode_DecodeASCII(sgt, 4, NULL))->str;
	qt = ((PyUnicodeObject*)PyUnicode_DecodeASCII(sqt, 6, NULL))->str;
	
	PyObject *module = PyImport_ImportModule("jinja2.utils");
	if (!module)
		return 0;
	markup = PyObject_GetAttrString(module, "Markup");
	Py_DECREF(module);

	return 1;
}

static PyObject*
escape_unicode(PyUnicodeObject *in)
{
	PyUnicodeObject *out;
	Py_UNICODE *outp;

	/* First we need to figure out how long the escaped string will be */
	int len = 0, erepl = 0, repl = 0;
	Py_UNICODE *inp = in->str;
	while (*(inp) || in->length > inp - in->str)
		switch (*inp++) {
		case '&':
			len += 5;
			++erepl;
			break;
		case '"':
			len += 6;
			++erepl;
			break;
		case '<':
		case '>':
			len += 4;
			++erepl;
			break;
		default:
			++len;
		}

	/* Do we need to escape anything at all? */
	if (!erepl) {
		Py_INCREF(in);
		return (PyObject*)in;
	}

	out = (PyUnicodeObject*)PyUnicode_FromUnicode(NULL, len);
	if (!out)
		return NULL;

	outp = out->str;
	inp = in->str;
	while (*(inp) || in->length > inp - in->str) {
		/* copy rest of string if we have replaced everything */
		if (repl == erepl) {
			Py_UNICODE_COPY(outp, inp, in->length - (inp - in->str));
			break;
		}
		/* regular replacements */
		switch (*inp) {
		case '&':
			Py_UNICODE_COPY(outp, amp, 5);
			outp += 5;
			++repl;
			break;
		case '"':
			Py_UNICODE_COPY(outp, qt, 6);
			outp += 6;
			++repl;
			break;
		case '<':
			Py_UNICODE_COPY(outp, lt, 4);
			outp += 4;
			++repl;
			break;
		case '>':
			Py_UNICODE_COPY(outp, gt, 4);
			outp += 4;
			++repl;
			break;
		default:
			*outp++ = *inp;
		};
		++inp;
	}

	return (PyObject*)out;
}


static PyObject*
soft_unicode(PyObject *self, PyObject *s)
{
	if (!PyUnicode_Check(s))
		return PyObject_Unicode(s);
	Py_INCREF(s);
	return s;
}


static PyObject*
escape(PyObject *self, PyObject *text)
{
	PyObject *s = NULL, *rv = NULL;

	/* we don't have to escape integers, bools or floats */
	if (PyInt_CheckExact(text) || PyLong_CheckExact(text) ||
	    PyFloat_CheckExact(text) || PyBool_Check(text) ||
	    text == Py_None) {
		PyObject *args = PyTuple_New(1);
		if (!args) {
			Py_DECREF(s);
			return NULL;
		}
		PyTuple_SET_ITEM(args, 0, text);
		return PyObject_CallObject(markup, args);
	}

	/* if the object has an __html__ method that performs the escaping */
	PyObject *html = PyObject_GetAttrString(text, "__html__");
	if (html) {
		rv = PyObject_CallObject(html, NULL);
		Py_DECREF(html);
		return rv;
	}

	/* otherwise make the object unicode if it isn't, then escape */
	PyErr_Clear();
	if (!PyUnicode_Check(text)) {
		PyObject *unicode = PyObject_Unicode(text);
		if (!unicode)
			return NULL;
		s = escape_unicode((PyUnicodeObject*)unicode);
		Py_DECREF(unicode);
	}
	else
		s = escape_unicode((PyUnicodeObject*)text);

	/* convert the unicode string into a markup object. */
	return PyObject_CallFunctionObjArgs(markup, (PyObject*)s, NULL);
}


static PyObject *
tb_set_next(PyObject *self, PyObject *args)
{
	PyTracebackObject *tb, *old;
	PyObject *next;

	if (!PyArg_ParseTuple(args, "O!O:tb_set_next", &PyTraceBack_Type, &tb, &next))
		return NULL;
	if (next == Py_None)
		next = NULL;
	else if (!PyTraceBack_Check(next)) {
		PyErr_SetString(PyExc_TypeError,
				"tb_set_next arg 2 must be traceback or None");
		return NULL;
	}
	else
		Py_INCREF(next);

	old = tb->tb_next;
	tb->tb_next = (PyTracebackObject*)next;
	Py_XDECREF(old);

	Py_INCREF(Py_None);
	return Py_None;
}


static PyMethodDef module_methods[] = {
	{"escape", (PyCFunction)escape, METH_O,
	 "escape(s) -> string\n\n"
	 "Convert the characters &, <, >, and \" in string s to HTML-safe\n"
	 "sequences. Use this if you need to display text that might contain\n"
	 "such characters in HTML."},
	{"soft_unicode", (PyCFunction)soft_unicode, METH_O,
	 "soft_unicode(object) -> string\n\n"
         "Make a string unicode if it isn't already.  That way a markup\n"
         "string is not converted back to unicode."},
	{"tb_set_next", (PyCFunction)tb_set_next, METH_VARARGS,
	 "Set the tb_next member of a traceback object."},
	{NULL, NULL, 0, NULL}		/* Sentinel */
};


#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
init_speedups(void)
{
	if (!init_constants())
		return;

	Py_InitModule3("jinja2._speedups", module_methods, "");
}
