"""a WSGI middleware server for CherryPy"""

__version__ = '0.1'
__license__ = 'MIT'
__author__ = 'Christian Wyglendowski <christian@dowski.com'

import cherrypy
from cherrypy._cpwsgi import WSGIServer, wsgiApp, CPHTTPRequest
from cherrypy._cpserver import Server

class WSGIHTTPRequest(CPHTTPRequest):
    def parse_request(self):
        """This basically flip-flops SCRIPT_NAME and PATH_INFO.

        Is there a reason why CP sets every path as "SCRIPT_NAME"?
        Does it hurt to set it to "PATH_INFO" instead?
        """
        CPHTTPRequest.parse_request(self)
        self.environ['PATH_INFO'] = self.environ.get('SCRIPT_NAME', '')
        if self.environ['PATH_INFO']:
            self.environ['PATH_INFO'] = '/' + self.environ['PATH_INFO']
        self.environ['SCRIPT_NAME'] = ''
        #print 'SCRIPT_NAME:', self.environ['SCRIPT_NAME']
        #print 'PATH_INFO:', self.environ['PATH_INFO']

class WSGIServerWithMiddleware(object):
    def __init__(self, app=wsgiApp, middleware=list()):
        for mw, conf in middleware:
            app = mw(app, **conf)
        self.wsgi_app = app
    def __call__(self):
        server = WSGIServer(self.wsgi_app)
        server.RequestHandlerClass = WSGIHTTPRequest
        return server

_serverClass = WSGIServerWithMiddleware
      
class MiddlewareServer(Server):
    def start(self, initOnly=False, serverClass=_serverClass, middleware=list()):
        serverClass = serverClass(middleware=middleware)
        Server.start(self, initOnly, serverClass)

if __name__ == '__main__':
    try:
        from paste.evalexception.middleware import EvalException
    except ImportError:
        print "Please install paste 0.4.2 or the latest Paste development code."
        print "(hint: easy_install -U Paste==dev)"
        import sys;sys.exit(1)
    
    class Root(object):
        @cherrypy.expose
        def index(self):
            yield "Some things are cool and some things are awesome<br>"
            yield "Get in <a href='/problem'>trouble</a><br>"
            yield cherrypy.request.browser_url + '<br>'
            yield cherrypy.request.path + '<br>'
            yield cherrypy.request.object_path + '<br>'

        @cherrypy.expose
        def problem(self):
            "error on purpose to show off EvalException"
            assert 0, "Houston, we have a problem."

    # we need this so that errors trickle down to the middleware
    cherrypy.config.update({'server.throw_errors':True})

    # mount our CherryPy apps
    cherrypy.root = Root()
    cherrypy.root.toor = Root()

    # override the standard server with the middleware server
    cherrypy.server = MiddlewareServer()

    # create our middleware "stack"
    # (a list of middleware that will chain together with
    # each other and finally CP
    mw = [(EvalException, {'global_conf':dict()})]

    # start the server with the middleware stack
    cherrypy.server.start(middleware=mw)

