#!/usr/bin/env python

import sys
# sys.path.insert(0, '/home/bb/projects/python')
# sys.path.insert(0, '/home/bb/public_html/pygci')
import pprint

from wsgiref.util import shift_path_info, request_uri

# the app registry
apps = {}
default = '_index'

def application(environ, start_response):
    """The main WSGI app.
    Dispatches to one of the registered apps."""
    app = shift_path_info(environ) or default
    try:
        return apps.get(app, _not_found)(environ, start_response)
    except:
        import traceback
        start_response('500 Internal error', [('Content-Type', 'text/html')])
        return [
            "<!DOCTYPE html>\n<h1>Internal error</h1>\n\n"
            "<p>The following exception occurred while handling a request to\n"
            "<code>", app, "</code>:\n\n<pre>\n",
            traceback.format_exc(), "</pre>\n"
        ]

def register(path):
    """Decorator to register the app at path."""
    def decorator(app):
        apps[path] = app
        return app
    return decorator

@register(default)
def _index(_, start_response):
    from xmlbuilder import builder
    f = builder(None, None)
    f._write('<!DOCTYPE html>')
    with f.html:
        f.h1('Registered WSGI applications')
        with f.ul:
            for p in sorted(apps.keys()):
                if p[0] == '_':
                    continue
                with f.li:
                    f.a(p, href=p)
                    if apps[p].__doc__:
                        f[apps[p].__doc__]

    start_response('200 OK', [('Content-Type', 'text/html')])
    return [str(f)]

def _not_found(environ, start_response):
    start_response('404 not found', [('Content-Type', 'text/plain')])
    return ['The WSGI application at ', environ['SCRIPT_NAME'], ' was not found']

@register('hi')
def hi(environ, start_response):
    """says Hi!"""
    start_response('200 OK', [('Content-Type', 'text/plain')])
    who = shift_path_info(environ) or 'world'
    return ['Hi, ', who, '!']

@register('charts')
def lastfm(environ, start_response):
    """shows a feed of the weekly last.fm artist charts"""
    environ['user_id'] = shift_path_info(environ)
    import charts
    return charts.application(environ, start_response)

@register('loved')
def lastfm(environ, start_response):
    """shows a feed of the loved last.fm tracks"""
    environ['user_id'] = shift_path_info(environ)
    import loved
    return loved.application(environ, start_response)

@register('env')
def env(environ, start_response):
    """shows the Python path, the request URI and the WSGI environment"""
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return [
        'sys.path = ', pprint.pformat(sys.path),
        '\n\nURI: ', request_uri(environ),
        '\n\nenviron = ', pprint.pformat(environ)
    ]

@register('mod_python')
def mod_python(environ, start_response):
    """mod_python compatibility layer"""
    from mod_python import apache, publisher
    req = apache.ModApacheRequest(environ)
    try:
        result = publisher.handler(req)
        if result != apache.OK:
            raise ApacheError, result
    except apache.ApacheError as e:
        start_response('%s whatever' % e.args[0], req.err_headers_out.items())
        return [repr(e), '\n\n', pprint.pformat(req.__dict__)]
    req.environ = None
    start_response('%s whatever' % req.status, req.headers())
    return [req.result]

@register('urls')
def urls(environ, start_response):
    import urls
    return urls.application(environ, start_response)

if __name__ == '__main__':
        from wsgiref.simple_server import make_server
        srv = make_server('', 8080, application)
        srv.serve_forever()