from repoze.bfg.configuration import Configurator
from repoze.bfg.url import route_url
from repoze.bfg.threadlocal import get_current_request
from repoze.bfg.exceptions import NotFound
from repoze.bfg.view import append_slash_notfound_view

from paste.httpserver import serve

from weberror.evalexception import EvalException

class Groundhog(object):
    def __init__(self, package):
        self.package = package
        self.config = Configurator()
        self.config.begin()
        self.config.add_renderer('groundhog', self.renderer_factory)
        self.config.add_view(append_slash_notfound_view, context=NotFound)

    def renderer_factory(self, name):
        def render(value, system):
            request = system.get('request')
            if request is not None:
                request.response_content_type = 'text/html'
            return value
        return render

    def mapply(self, func):
        def mapplied(request):
            return func(**request.matchdict)
        return mapplied

    def route(self, pattern, methods=('GET', 'HEAD')):
        def decorator(func):
            endpoint = func.__name__
            self.config.add_route(endpoint, pattern)
            for method in methods:
                view = self.mapply(func)
                self.config.add_view(view, route_name=endpoint,
                                     request_method=method,
                                     renderer='groundhog')
            return func
        return decorator

    def run(self, host=None, port=8080, debug=False):
        self.config.end()
        app = self.config.make_wsgi_app()
        if debug:
            app = EvalException(app)
        serve(app, host, port)

    def url_for(self, endpoint, *arg, **options):
        if not isinstance(endpoint, basestring):
            endpoint = endpoint.__name__
        request = get_current_request()
        return route_url(endpoint, request, *arg, **options)

# application

app = Groundhog(__name__)

@app.route('/')
def aview():
    return ('<html><a href="%s">foo 1<a/></html>' %
            app.url_for('foo', id='1', _anchor='fudge'))

@app.route('/foo/:id')
def foo(id=None):
    return '<html>%s</html>' % id

@app.route('/slashending/')
def slashending():
    return 'ends in a slash'

@app.route('/exception')
def exc():
    raise RuntimeError('exception view')

if __name__ == '__main__':
    app.run(debug=True)
    

