# -*- coding: utf8 -*-
'''
**********************************************
*       P R O T O C O L - C L A S S
*       for the species2000 protocol
**********************************************
$RCSfile: sp2k_protocol.py,v $
$Revision: 911 $
$Author: markus $
$Date: 2008-04-30 23:52:39 +0200 (Mi, 30. Apr 2008) $

The species2000 protocol uses no XML for querying but CGI parameters.
The response is a fixed schema knwon as the Common Data Model (CDM).
This is built into the pywrapper via its namespaces:
http://www.sp2000.org/CDMSchema1.3
'''

import types
from biocase.wrapper.errorclasses         import *
from biocase.wrapper.protocol.base_protocol import ProtocolBaseClass
from biocase.wrapper.protocol.species2000.sp2k_request  import RequestClass
from biocase.wrapper.protocol.species2000.sp2k_response import ResponseClass
from biocase.wrapper.psf import ProviderSetup
from biocase.wrapper.cmf_base        import CMFClass

import biocase.configuration
cfg = biocase.configuration.Cfg()

import logging
log = logging.getLogger("pywrapper.protocol.sp2k")

# ------------------------------------------------------------------------------------
class ProtocolClass(ProtocolBaseClass):
    '''The main protocol class accepting a standard API and managing requests and responses.'''
    NAME="Species2000"
    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def __init__(self, dsaObj, diagnosticsHandler):
        log.info("Species2000 SPICE protocol used.")
        ProtocolBaseClass.__init__(self, dsaObj, diagnosticsHandler, RequestClass=RequestClass, ResponseClass=ResponseClass)
    
    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def processRequest(self):
        '''Starts to process the request and prepares output object.'''
        # test if all objects are existing
        if self.psfObj is None:
            log.warn('PyWrapper instance is missing its configurations!')
        elif self.requestObj is None:
            log.warn('PyWrapper instance is missing a request!')
        else:
            # ***************
            # process request
            # ***************
            try:
                # purely static CMFs
                if self.requestObj.type == "static":
                    # create CMF object of the response-CMF for output of XML
                    try:
                        # build new CMF object
                        CMFObject = CMFClass()
                        CMFObject.loadCMFdata(self.psfObj.getCMFfilename(self.requestObj.resSchema), psfObj=self.psfObj)
                        # cut off the unused parts:
                        for path in self.requestObj.removeCMFSubtreePaths:
                            CMFObject.removeSubtree(path, self.psfObj)
                    except CouldNotPickleError:
                        pass
                    except:
                        raise CMFError(cmf=self.requestObj.resSchema)
                    # log.debug(unicode(CMFObject.fullRepr() ))
                    etree = CMFObject.createXMLResultET( [[]] )
                    self.responseObj.setSearchContent(etree)
                # search
                elif self.requestObj.type == "search":
                    # chose DBmodule, connect to DB.
                    from biocase.wrapper.operations import getOperationsObjectForDBMod
                    operationObj = getOperationsObjectForDBMod(self.psfObj    , self.responseObj, self.requestObj.removeCMFSubtreePaths, self.requestObj.rtype)
                    # SEARCH
                    # check if requested schemas are supported for output
                    self.requestObj.areSchemasSupported()
                    (self.resultET, self.resultStatus) = operationObj.search(self.requestObj)
                    # copy result to the response object
                    self.responseObj.setSearchContent(self.resultET, self.resultStatus)
                    # log number of results
                    self.logObj.setResponseStatus(self.resultStatus.count, self.resultStatus.drop, self.resultStatus.total)
                else:
                    log.warn("Unknown Request-type : " + str(self.requestObj.type))
            except:
                log.error('Request processing aborted due to fatal error !')

