# -*- coding: utf8 -*-
'''
SAX HANDLERS for PSF
######################
# SAX HANDLERS 
# for PSF
######################
$RCSfile: psf_handler.py,v $
$Revision: 899 $
$Author: markus $
$Date: 2008-04-29 20:11:05 +0200 (Di, 29. Apr 2008) $
'''


import os
from os.path                              import join as pathjoin
from biocase.wrapper.errorclasses         import *
from biocase.tools.various_functions      import isTrue
from biocase.tools.saxbasehandler         import SaxBaseHandler
from biocase.wrapper.typeconverter        import DBAttributeClass
from biocase.wrapper.graph.tablegraph     import tableGraphClass, tableAliasClass

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

import logging
log=logging.getLogger("pywrapper.psf.handler")


# ----------------------------------------------------------------------------
class SupportedSchema:
    # conceptMappingFile is the absolute filename.
    def __init__(self):
        self.name = None
        self.request = 1
        self.response = 1
        self.conceptMappingFile = None
        
    def setName(self, name):
        n = name.lower()
        self.name = n

# ------------------------------------------------------------------------------------
class providerConfigHandler(SaxBaseHandler):
    '''parses the provider setup configuration file 
    and fills a psf object with its data.'''
    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def __init__(self, psfObj):
        self.psfObj = psfObj
        # list of tablealias information used to init the graph
        self._aliases = []
        self._isHost = 0
        self._isDB = 0
        self._isSupportedSchemas = 0
        self._isWrapperBehavior  = 0
        self._isPK = 0
        self._isFK = 0
        self._alias = []
        self._fkTarget = None
        SaxBaseHandler.__init__(self)
    
    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def startElement(self, name, attrs):
        name, attrs = SaxBaseHandler.startElement(self, name, attrs)
        if name == 'Provider':
            self.psfObj.adminpassword = attrs.get('adminpassword',None)
            self.psfObj.loglevel = attrs.get('loglevel',logging.INFO)
        elif name == 'Host':
            self._isHost = 1
        elif name == 'DB':
            self._isDB = 1
        elif name == 'SupportedSchemas':
            self._isSupportedSchemas   = 1
        elif name == 'WrapperBehavior':
            self._isWrapperBehavior   = 1
        elif self._isSupportedSchemas > 0:
            if name == 'Schema':
                # create new schema object
                self._ss = SupportedSchema()
                self._ss.setName(attrs.get('namespace',None))
                self._ss.request = isTrue(attrs.get('request',0))
                self._ss.response = isTrue(attrs.get('response',0))
        elif self._isDB > 0:
            if name == 'TableAlias':
                tao = tableAliasClass()
                self._alias = tao
                self._alias.alias = attrs.get('alias',None)
                self._alias.table = attrs.get('tablename',None)
            elif name == 'PrimaryKey':
                self._isPK = 1
            elif name == 'ForeignKey':
                self._isFK = 1
                self._alias.addFK(attrs.get('target',None), [])
            elif name == 'Attribute':
                DBAttrObj = DBAttributeClass()
                DBAttrObj.table = self._alias.alias
                DBAttrObj.type = attrs.get('dbType','unicode')
                if self._isPK > 0:
                    # this attribute is part of the primary key
                    self._alias.pk.append(DBAttrObj)
                elif self._isFK > 0:
                    # this attribute is part of a foreign key
                    fkObj = self._alias.getLastFk()
                    fkObj.addKey(DBAttrObj)

    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def endElement(self, name):
        name=SaxBaseHandler.endElement(self, name)
        if name == 'Host':
            self._isHost = 0
        elif name == 'DB':
            self._isDB = 0
            tg = tableGraphClass()
            # add all aliases to graph:
            tg.buildGraph(self._aliases)
            self.psfObj.tablegraph = tg
        elif name == 'SupportedSchemas':
            self._isSupportedSchemas   = 0
        elif name == 'WrapperBehavior':
            self._isWrapperBehavior   = 0
        elif self._isHost > 0:
            if name == 'User':
                self.psfObj.user = self._value
            elif name == 'Password':
                self.psfObj.password = self._value
            elif name == 'Datasource':
                self.psfObj.database = self._value
            elif name == 'DB_IP':
                self.psfObj.dbIP = self._value
            elif name == 'DBMS':
                self.psfObj.dbms = self._value
        elif self._isDB > 0:
            if name == 'TextEncoding':
                self.psfObj.encoding = str(self._value)
            elif name == 'TableAlias':
                self._aliases.append(self._alias)
            elif name == 'PrimaryKey':
                self._isPK = 0
            elif name == 'ForeignKey':
                self._isFK = 0
            elif name == 'Attribute':
                if self._isPK > 0:
                    # attribute of the PK
                    self._alias.pk[-1].attr = self._value
                elif self._isFK > 0:
                    # attribute is part of a FK
                    fkObj = self._alias.getLastFk()
                    fkObj.getLastKey().attr = self._value
        elif self._isSupportedSchemas > 0:
            if name == 'Schema':
                if self.psfObj.configDir is not None:
                    self._ss.conceptMappingFile = pathjoin(self.psfObj.configDir, self._value)
                self.psfObj.schemas[self._ss.name] = self._ss
        #
        # optional settings overriding the wrapper config file:
        #
        elif self._isWrapperBehavior > 0:
            if name == 'RecordResultLimit':
                try:
                    self.psfObj.recLimit = int(self._value)
                    if self.psfObj.recLimit <= 0:
                        self.psfObj.recLimit = 0
                except:
                    pass
        self._value = ''





if __name__ ==  "__main__":
    import biocase.wrapper.psf
    import xml.sax
    psf=biocase.wrapper.psf.ProviderSetup(None)
    ch = providerConfigHandler(psf)
    fn ="/Users/markus/Sites/bps2/templates/datasources/pontaurus/provider_setup_file.xml"
    xml.sax.parse(fn, ch)
    print "YEAH !!!"
    #print ch.psfObj
