# -*- coding: utf-8 -*_
# Template language benchmarks
#
# Objective: Generate a 1000x10 HTML table as fast as possible.
# adapted for jinja 1
#
# Author: Jonas Borgström <jonas@edgewall.com>
# Author: Armin Ronacher <armin.ronacher@active-4.com>

import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))

import cgi
import timeit
import jdebug
from StringIO import StringIO


try:
    from genshi.builder import tag
    from genshi.template import MarkupTemplate
    have_genshi = True
except ImportError:
    have_genshi = False

from jinja import Environment

try:
    from django.conf import settings
    settings.configure()
    from django.template import Context as DjangoContext
    from django.template import Template as DjangoTemplate
    have_django = True
except ImportError:
    have_django = False

try:
    from kid import Template as KidTemplate
    have_kid = True
except ImportError:
    have_kid = False

try:
    from Cheetah.Template import Template as CheetahTemplate
    have_cheetah = True
except ImportError:
    have_cheetah = False

try:
    from mako.template import Template as MakoTemplate
    have_mako = True
except ImportError:
    have_mako = False

table = [dict(zip('abcdefghij', map(unicode,range(1, 11))))
          for x in range(1000)]

if have_genshi:
    genshi_tmpl = MarkupTemplate("""
<table xmlns:py="http://genshi.edgewall.org/">
<tr py:for="row in table">
<td py:for="c in row.values()" py:content="c"/>
</tr>
</table>
""")

if have_kid:
    kid_tmpl = KidTemplate("""
<table xmlns:py="http://purl.org/kid/ns#">
<tr py:for="row in table">
<td py:for="c in row.values()" py:content="c"/>
</tr>
</table>
""")

if have_django:
    django_tmpl = DjangoTemplate("""
<table>
{% for row in table %}
<tr>{% for col in row.values %}<td>{{ col }}</td>{% endfor %}</tr>
{% endfor %}
</table>
""")

jinja_tmpl = Environment().from_string('''
<table>
{% for row in table -%}
<tr>{% for col in row.values() %}<td>{{ col }}</td>{% endfor %}</tr>
{% endfor %}
</table>
''')

if have_cheetah:
    cheetah_tmpl = CheetahTemplate('''
<table>
#for $row in $table
<tr>
#for $col in $row.values()
<td>$col</td>
#end for
</tr>
#end for
</table>
''', searchList=[{'table': table, 'escape': cgi.escape}])

if have_mako:
    mako_tmpl = MakoTemplate('''
<table>
% for row in table:
<tr>
% for col in row.values():
    <td>${col}</td>
% endfor
</tr>
% endfor
</table>
''')

def test_django():
    """Django Templates"""
    if not have_django:
        return
    context = DjangoContext({'table': table})
    django_tmpl.render(context)

def test_jinja():
    """Jinja Templates"""
    jinja_tmpl.render(table=table)

def test_genshi():
    """Genshi Templates"""
    if not have_genshi:
        return
    stream = genshi_tmpl.generate(table=table)
    stream.render('html', strip_whitespace=False)

def test_kid():
    """Kid Templates"""
    if not have_kid:
        return
    kid_tmpl.table = table
    kid_tmpl.serialize(output="html")

def test_cheetah():
    """Cheetah Templates"""
    if not have_cheetah:
        return
    cheetah_tmpl.respond()

def test_mako():
    """Mako Templates"""
    if not have_mako:
        return
    mako_tmpl.render(table=table)


def run(which=None, number=10):
    tests = ['test_django', 'test_jinja', 'test_kid', 'test_genshi',
             'test_cheetah', 'test_mako']

    if which:
        tests = filter(lambda n: n[5:] in which, tests)

    for test in [t for t in tests if hasattr(sys.modules[__name__], t)]:
        t = timeit.Timer(setup='from __main__ import %s;' % test,
                         stmt='%s()' % test)
        time = t.timeit(number=number) / number

        if time < 0.00001:
            result = '   (not installed?)'
        else:
            result = '%16.2f ms' % (1000 * time)
        print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)


if __name__ == '__main__':
    which = [arg for arg in sys.argv[1:] if arg[0] != '-']

    if '-p' in sys.argv:
        from cProfile import Profile
        from pstats import Stats
        p = Profile()
        p.runcall(test_jinja)
        stats = Stats(p)
        stats.strip_dirs()
        stats.sort_stats('time', 'calls')
        stats.print_stats()
    else:
        run(which)
