import py
import traceback
from lxml import etree
from templess import templess
import helpers

"""handlers

all handlers *except for the sidebar and macro ones* grok the context dict
as their only argument, and return a dict with keys 'title' (should have a
string value) and 'body' (can be a string, etree node, list of strings or
etree nodes, or a list of dicts, see 'templess' documentation for more
details, it's used for t:content)

the sidebar handler gets also only the context as argument, but returns a
list of etree nodes, the macro handler groks context and the content of another
handler, and returns a string
"""

def htmlhandler(context):
    f = py.path.local(context['request'].filename)
    html = f.read()
    tree = etree.fromstring(html)
    content = {
        'title': tree.xpath('//title')[0].text,
        'body': tree.xpath('//body')[0],
    }
    return content

restcache = {}
def resthandler(context):
    import rest
    filename = context['request'].filename
    fpath = py.path.local(filename)
    if restcache.has_key(filename):
        mtime, data = restcache[filename]
        if mtime == fpath.mtime(): 
            return data
    tree = rest.rest2etree(fpath)
    ret = {
        # use the first heading as title, some docutils versions don't produce
        # a document title
        'title': tree.xpath('//h1[@class=\'title\']')[0].text,
        'body': tree.xpath('//body/*'),
    }
    restcache[filename] = (fpath.mtime(), ret)
    return ret
    
def status404handler(context):
    content = {
        'title': 'Not found',
        'body': '%s not found!' % (
            py.path.local(context['request'].filename).basename,),
    }
    return content

def downloadshandler(context):
    import downloads
    return {
        'title': 'Downloads',
        'body': downloads.downloads.render(context),
    }

def screenshotshandler(context):
    import screenshots
    body = screenshots.screenshots.render(context)
    if context['headers']['content-type'].startswith('image'):
        return body
    return {
        'title': 'Screenshots',
        'body': body,
    }

def sidebarhandler(context):
    import sidebar
    return sidebar.sidebar.render(context)

def macrohandler(context, content):
    import handler_registry
    request = context['request']
    options = request.get_options()
    sidebarhandler = handler_registry.sidebarhandler
    env = {
        'title': content['title'],
        'sidebar': sidebarhandler(context),
        'body': content['body'],
        'stylehref': options['stylehref'],
        'logosrc': options['logosrc'],
    }
    f = helpers.templatepath(request) / 'macro.html'
    t = templess.template(f, options.get('charset', 'UTF-8'))
    return t.render_to_string(env)

def errorhandler(exc, e, tb, context):
    head = etree.Element('h1')
    head.text = '%s - %s' % (exc, e)
    pre = etree.Element('pre')
    pre.text = '\n'.join(traceback.format_tb(tb))
    return {
        'title': exc,
        'body': [head, pre],
    }

