#
# -*- coding: utf-8 -*-

'''
$RCSfile: datasources.py,v $
$Revision: 996 $
$Author: markus $
$Date: 2010-09-16 11:33:31 +0200 (Do, 16. Sep 2010) $
General filesystem methods all webapps need.
'''

############################################################################################################
#
#   IMPORTS
#
#===========================================================================================================

import os, string, shutil
from types import *
from biocase.cmfinfo            import CMFListClass
from biocase.wrapper.psf        import ProviderSetup
from biocase.tools.caching      import getCachedDsaFile, getCachedFilename

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

import logging
log=logging.getLogger("lib.datasource")

############################################################################################################
#
#   CLASSES
#
#===========================================================================================================
 
class Datasource:
    # ------------------------------------------------------------------------------------
    def __init__(self, name):
        self.name     = name
        self.psfObj   = None
        self.dbmodObj = None
        # temp references only created when needed at all
        self._cmfListObj   = None
        
    # ------------------------------------------------------------------------------------
    def __repr__(self):
        return "DSAobj:%s"%self.name
        
    # ------------------------------------------------------------------------------------
    def getDsaDir(self):
        return os.path.join(cfg.dsaLocator, self.name)

    # ------------------------------------------------------------------------------------
    def getSchemaListObj(self):
        if self._cmfListObj is None:
            self._cmfListObj = CMFListClass()
            self._cmfListObj.addSchemasFromDir( self.getDsaDir() )
        return self._cmfListObj
    
    # ------------------------------------------------------------------------------------
    def getDeletedSchemaListObj(self):                
        self._cmfListObj = CMFListClass()        
        self._cmfListObj.addDeletedSchemasFromDir( self.getDsaDir() )
        return self._cmfListObj

    # ------------------------------------------------------------------------------------
    def getBakFileName(self, schema):                
        self._cmfListObj = CMFListClass()        
        return self._cmfListObj.getBakFileName( self.getDsaDir(), schema )        

    # ------------------------------------------------------------------------------------
    def getSchemaNameList(self):
        slObj = self.getSchemaListObj()
        return [sObj.name for sObj in slObj]

    # ------------------------------------------------------------------------------------
    def getAbsPSFilePath(self):
        return os.path.join(cfg.dsaLocator, self.name, cfg.pywrapper.psfFile)

    # ------------------------------------------------------------------------------------
    def getAbsTempPSFilePath(self):
        psfTemp=getCachedDsaFile(cfg.pywrapper.psfFile[:-4]+'_tmpCfgTool.xml', self.name)
        return psfTemp

    # ------------------------------------------------------------------------------------
    def getPSFObj(self, tmp=False):
        '''Reads the PSF for a given datasource. If tmp is true read from the temporary PSF.'''
        if self.psfObj is None:
            if tmp:
                # read temporary PSF
                absFilePath = self.getAbsTempPSFilePath()
            else:
                # read real PSF
                absFilePath = self.getAbsPSFilePath()
            self.psfObj = ProviderSetup(dsaObj=self)
            self.psfObj.readPSFile(filename=absFilePath)
        return self.psfObj

    # ------------------------------------------------------------------------------------
    def getBioCASeAccessPoint(self):
        return cfg.getAccessPoint(self.name, "biocase")

    # ------------------------------------------------------------------------------------
    def getSPICEAccessPoint(self):
        return cfg.getAccessPoint(self.name, "spice")

    # ------------------------------------------------------------------------------------
    def getDbmodObj(self):
        if self.dbmodObj is None:
            from biocase.wrapper.operations import getOperationsObjectForDBMod
            try:
                self.dbmodObj = getOperationsObjectForDBMod(psfObj=self.getPSFObj())
            except:
                log.error("Could not get operation module")
                self.dbmodObj = None
        return self.dbmodObj
        
    # ------------------------------------------------------------------------------------
    def getDBConnectionStatus(self):
        if self.getDbmodObj() is not None:
            return cfg.html.dbConnectionStatusGood
        else:
            return cfg.html.dbConnectionStatusBad


############################################################################################################
#
#   FUNCTIONS
#
#===========================================================================================================

# ------------------------------------------------------------------------------------
def getDsaList():
    dsalist = []
    for dsa in os.listdir(cfg.dsaLocator):
        if os.path.isdir(os.path.join(cfg.dsaLocator, dsa)) and os.path.isfile(os.path.join(cfg.dsaLocator, dsa, 'provider_setup_file.xml')):
            dsalist.append( Datasource(dsa) )
    return dsalist

# ------------------------------------------------------------------------------------
def getDsaInRecycleBinList():
    dsalist = []
    recycleDir = str(cfg.dsaLocator) + ".recycle.bin"
    if os.path.exists(recycleDir):
        for dsa in os.listdir(recycleDir):
            if os.path.isdir(os.path.join(recycleDir, dsa)) and os.path.isfile(os.path.join(recycleDir, dsa, 'provider_setup_file.xml')):
                dsalist.append( Datasource(dsa) )
    return dsalist

# ------------------------------------------------------------------------------------
def delDsa(dsa):
    pass

# ------------------------------------------------------------------------------------
def copy_directory(source, target):
    if not os.path.exists(target):
        os.mkdir(target)
    for root, dirs, files in os.walk(source):
        if '.svn' in dirs:
            dirs.remove('.svn')  # don't visit .svn directories           
        for file in files:
            if os.path.splitext(file)[-1] in ('.pyc', '.pyo', '.fs'):
                continue
            from_ = os.path.join(root, file)           
            to_ = from_.replace(source, target, 1)
            to_directory = os.path.split(to_)[0]
            if not os.path.exists(to_directory):
                os.makedirs(to_directory)
            shutil.copyfile(from_, to_)
            
# ------------------------------------------------------------------------------------            
def createDsa(dsa, template):
    '''Create a new datasource directory and copy the template files to it.'''
    # check dsa spelling. replace spaces with underscore
    if dsa is None:
        log.warn("Datasource name cannot be None!")
        return False
    dsa = dsa.replace(' ', '_')
    # abs path to new dir
    dsaDir = os.path.join(cfg.dsaLocator, dsa)
    # path to template dir
    tmplDir = os.path.join(cfg.dsaTemplateLocator, template)
    # does it already exist?
    if os.path.isdir( dsaDir ):
        log.warn("Datasource %s does already exist!"%dsa)
        return False
    elif not os.path.isdir(tmplDir):
        log.warn("Datasource template %s does not exist!"%template)
        return False
    else:
        # create directory and copy template files recursively
        #IGNORE_PATTERNS = ('*.pyc','CVS','^.git','tmp','.svn') # python 2.6
        #shutil.copytree(tmplDir, dsaDir, ignore=shutil.ignore_patterns(IGNORE_PATTERNS))
        copy_directory(tmplDir, dsaDir)
        log.info("Datasource %s created successfully!"%dsa)
        return True
    return False
    
    
    

##############################
if __name__ ==  "__main__":
    # start logging
    import biocase.initlogs
    dsa='pontoflex_maximus'
    biocase.initlogs.initWrapperLogging(dsa)
    dsaObj = Datasource(dsa)
    print dsaObj.getPSFObj()