#    This file is part of WebBox.
#
#    Copyright 2011-2012 Daniel Alexander Smith
#    Copyright 2011-2012 University of Southampton
#
#    WebBox is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    WebBox is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with WebBox.  If not, see <http://www.gnu.org/licenses/>.

import logging, traceback
import logging, urllib2, uuid, rdflib, os, traceback, mimetypes, shutil, json
from twisted.web.resource import Resource
from webbox.webserver.session import WebBoxSession, ISession
from webbox.webserver.handlers.base import BaseHandler
from webbox.objectstore_async import IncorrectPreviousVersionException

class BoxHandler(BaseHandler):
    base_path = ''
    def options(self, request):
        self.return_ok(request)
        
    def do_GET(self,request):
        token = self.get_token(request)
        if not token:
            return self.return_forbidden(request)
        store = token.store
        if "graph" in request.args:
            # graph URI specified, so return the objects in that graph
            graph_uri = request.args["graph"][0]
            obj = store.get_latest(graph_uri)
            jsondata = json.dumps(obj, indent=2)
            return self.return_ok(request, {"data":jsondata})
        else:
            # no graph URI specified, so return the list of graph URIs
            def callback(uris):
                jsondata = json.dumps(uris, indent=2)
                return self.return_ok(request, {"data": jsondata})
            store.get_graphs(callback)
            pass
        pass
    def do_PUT(self,request):
        token = self.get_token(request)
        if not token:
            return self.return_forbidden(request)
        store = token.store
        jsondata = request.content.read()
        objs = json.loads(jsondata)
        if type(objs) == type([]):
            # multi object put            
            if "graph" not in request.args:
                return self.return_bad_request(request,"Specify a graph URI with &graph=")
            if "version" not in request.args:
                return self.return_bad_request(request,"Specify a previous version with &version=")
            graph_uri = request.args['graph'][0]
            prev_version = int(request.args['version'][0])
            try:
                new_version_info = store.add(graph_uri, objs, prev_version)
                return self.return_created(request,{"data":new_version_info})                
            except IncorrectPreviousVersionException as ipve:
                logging.debug("Incorrect previous version")
                actual_version = ipve.version
                return self.return_obsolete(request,{"description": "Document obsolete. Please update before putting", '@version':actual_version})            
        else:
            # single object put
            return self.return_bad_request(request,"Single object PUT not supported, PUT an array to create/replace a named graph instead")
        pass
    
    # ## @TODO ::
    # def handle_update(self,request):
    #     """ Handle calls to the Journal update URL. """
    #     since_repository_hash = None
    #     if "since" in request.args:
    #        since_repository_hash = request.args['since'][0]                        
    #     journal = Journal(os.path.join(self.config['webbox_dir'], self.config['journal']))
    #     uris_changed = journal.since(since_repository_hash)
    #     logging.debug("URIs changed: %s" % str(uris_changed))

    #     if len(uris_changed) > 0:

    #         ntrips = ""
    #         for uri in uris_changed:
    #             query = "CONSTRUCT {?s ?p ?o} WHERE { GRAPH <%s> {?s ?p ?o}}" % uri
    #             logging.debug("Sending query for triples as: %s " % query)

    #             result = self.webbox.query_store.query(query, {"Accept": "text/plain"})
    #             # graceful fail per U

    #             rdf = result['data']
    #             ntrips += rdf + "\n"

    #         # TODO conneg
    #         rdf_type = "text/plain" # text/plain is n-triples (really)

    #         return {"data": ntrips, "status": 200, "reason": "OK", "type": rdf_type}

    #     else:
    #         # no update
    #         logging.debug("Client is up to date")
    #         return {"data": "", "status": 204, "reason": "No Content"}
    #     pass

BoxHandler.subhandlers = [
    {
        "prefix": "*",            
        'methods': ['GET'],
        'require_auth': False,
        'require_token': True,
        'handler': BoxHandler.do_GET,
        'accept':['application/json'],
        'content-type':'application/json'
        },
    {
        "prefix": "*",            
        'methods': ['PUT'],
        'require_auth': False,
        'require_token': True,
        'handler': BoxHandler.do_PUT,
        'accept':['application/json'],
        'content-type':'application/json'        
        },
    {
        'prefix':'*',
        'methods': ['OPTIONS'],
        'require_auth': False,
        'require_token': False,
        'handler': BaseHandler.return_ok,
        'content-type':'text/plain', # optional
        'accept':['application/json']                
        }
]

        

@@ -1984,16 +1984,30 @@
 _graphs(
+).addCallback(
 callback

Fix callback in get_graphs