#!/usr/bin/env python
# http://www.prescod.net/rest/mistakes/
import sys
import cherrypy
from httplib import CREATED, NO_CONTENT, METHOD_NOT_ALLOWED

requestMethodNames = [
    'GET', 'HEAD', 'POST', 'PUT',
    'DELETE', 'TRACE', 'OPTIONS', 'CONNECT',
]


def restful(alsoExpose=True):
    def restfulDeco(function):
        def restfulDispatch(self, *a, **b):
            name, verb = function.__name__, cherrypy.request.method.lower()
            assert verb.upper() in requestMethodNames
            
            try:
                method = getattr(self, '%s_%s' % (name, verb))
            except (AttributeError, ):
                raise cherrypy.HTTPError(METHOD_NOT_ALLOWED, 'Method Not Allowed')

            results = method(*a, **b)
            if verb == 'put':
                cherrypy.response.status = '%s Created' % (CREATED, )
            elif not results:
                cherrypy.response.status = '%s No Content' % (NO_CONTENT, )
                
            return results

        if alsoExpose:
            cherrypy.expose(restfulDispatch)
        
        return restfulDispatch


    return restfulDeco


class Test:
    @cherrypy.expose()
    def index(self):
        return '''
        <html>
        <form action='/test' method='POST'>
        <input type='text' name='foo' /><br />
        <input type='text' name='bar' /><br />
        <input type='submit' />
        </form>
        </html>
        '''

    @restful()
    def test(self):
        ## this method is discarded and replaced with the results of the
        ## restful decorator.
        pass


    def test_post(self, foo, bar):
        ## post data to this resource.  the restful wrapper will not interfere. 
        return '''
        <html>
        POST foo="%s", bar="%s" to resource "%s"
        </html>
        ''' % (foo, bar, cherrypy.request.path)


    def test_put(self):
        ## put data to this resource.  the restful wrapper will send 201 Created.
        url = cherrypy.request.path
        content = cherrypy.request.body
        content = content.read()


    def test_delete(self):
        # delete a resource.  by returning none, the restful wrapper will send 204 No Content
        pass


cherrypy.root = Test()
cherrypy.server.start()
