#!/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>\r\n<h1>Internal error</h1>\r\n\r\n"
	    "<p>The following exception occurred while handling a request to\r\n"
	    "<code>", app, "</code>:\r\n\r\n<pre>\r\n",
	    traceback.format_exc(), "</pre>\r\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),
        '\r\n\r\nURI: ', request_uri(environ),
        '\r\n\r\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()