# basic.py - basic benchmarks adapted from Genshi
# Copyright (C) 2006 Edgewall Software
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in
#     the documentation and/or other materials provided with the
#     distribution.
#  3. The name of the author may not be used to endorse or promote
#     products derived from this software without specific prior
#     written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from cgi import escape
import os
from StringIO import StringIO
import sys
import timeit

__all__ = ['mako', 'mako_inheritance', 'cheetah', 'django', 'myghty', 'genshi', 'kid']

def genshi(dirname, verbose=False):
    from genshi.template import TemplateLoader
    loader = TemplateLoader([dirname], auto_reload=False)
    template = loader.load('template.html')
    def render():
        data = dict(title='Just a test', user='joe',
                    items=['Number %d' % num for num in range(1, 15)])
        return template.generate(**data).render('xhtml')

    if verbose:
        print render()
    return render

def myghty(dirname, verbose=False):
    from myghty import interp
    interpreter = interp.Interpreter(component_root=dirname)
    def render():
        data = dict(title='Just a test', user='joe',
                    items=['Number %d' % num for num in range(1, 15)])
        buffer = StringIO()
        interpreter.execute("template.myt", request_args=data, out_buffer=buffer)
        return buffer.getvalue()
    if verbose:
        print render()
    return render

def mako(dirname, verbose=False):
    from mako.template import Template
    from mako.lookup import TemplateLookup
    lookup = TemplateLookup(directories=[dirname], filesystem_checks=False)
    template = lookup.get_template('template.html')
    def render():
        return template.render(title="Just a test", user="joe", list_items=[u'Number %d' % num for num in range(1,15)])
    if verbose:
        print template.code, render()
    return render
mako_inheritance = mako

def cheetah(dirname, verbose=False):
    from Cheetah.Template import Template
    filename = os.path.join(dirname, 'template.tmpl')
    template = Template(file=filename)
    def render():
        template.__dict__.update({'title': 'Just a test', 'user': 'joe',
                                  'list_items': [u'Number %d' % num for num in range(1, 15)]})
        return template.respond()

    if verbose:
        print dir(template)
        print template.generatedModuleCode()
        print render()
    return render

def django(dirname, verbose=False):
    from django.conf import settings
    settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')])
    from django import template, templatetags
    from django.template import loader
    templatetags.__path__.append(os.path.join(dirname, 'templatetags'))
    tmpl = loader.get_template('template.html')

    def render():
        data = {'title': 'Just a test', 'user': 'joe',
                'items': ['Number %d' % num for num in range(1, 15)]}
        return tmpl.render(template.Context(data))

    if verbose:
        print render()
    return render

def kid(dirname, verbose=False):
    import kid
    kid.path = kid.TemplatePath([dirname])
    template = kid.Template(file='template.kid')
    def render():
        template = kid.Template(file='template.kid',
                                title='Just a test', user='joe',
                                items=['Number %d' % num for num in range(1, 15)])
        return template.serialize(output='xhtml')

    if verbose:
        print render()
    return render


def run(engines, number=2000, verbose=False):
    basepath = os.path.abspath(os.path.dirname(__file__))
    for engine in engines:
        dirname = os.path.join(basepath, engine)
        if verbose:
            print '%s:' % engine.capitalize()
            print '--------------------------------------------------------'
        else:
            print '%s:' % engine.capitalize(),
        t = timeit.Timer(setup='from __main__ import %s; render = %s(r"%s", %s)'
                                       % (engine, engine, dirname, verbose),
                                 stmt='render()')
            
        time = t.timeit(number=number) / number
        if verbose:
            print '--------------------------------------------------------'
        print '%.2f ms' % (1000 * time)
        if verbose:
            print '--------------------------------------------------------'


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

    verbose = '-v' in sys.argv

    if '-p' in sys.argv:
        import hotshot, hotshot.stats
        prof = hotshot.Profile("template.prof")
        benchtime = prof.runcall(run, engines, number=100, verbose=verbose)
        stats = hotshot.stats.load("template.prof")
        stats.strip_dirs()
        stats.sort_stats('time', 'calls')
        stats.print_stats()
    else:
        run(engines, verbose=verbose)
