#!/usr/bin/env python
import os,os.path,string
import sys
import xml.dom.minidom
from optparse import OptionParser
class mappingGenerator:
    def __init__(self):
        """
        Generate mapping xml file for a given class with default mapping rules. The result xml file can be customised by the user. The mapping xml file name rule: classname_classversion_mappingversion.xml where the classversion parameter is taken from classes_def.xml. If class_version parameter is not present in classes_def.xml, the schema evolution is disabled for this class and this command will fail. The output file is classname_classversion_mappingversion.xml. The pool container name is equivalent to classname_mappingversion
        usage: %prog [options]
        -c, --classname : the class to generate mapping(required)
        -d, --dictionary : dictionary ( default to classes_def.xml dir SubsystemnamePackagename )
        -P, --path : path to classes_def.xml (default to current Subsystem/Package/src)
        -m, --mappingversion : mapping version (default to automatic_default)
                
        -v, --verbose: verbose mode
        -h, --help: print usage
        """
        self.__verbose=False
        cmsswbase=os.getenv('CMSSW_BASE')
        currentdir=os.getcwd()
        self.__path=currentdir
        if cmsswbase == None :
            raise ValueError, "cmssw environment variables not set"
        self.__classversion=""
        self.__classname=""
        self.__mappinglabel="automatic_default"
        self.__mappingversion="_".join([self.__classname, self.__mappinglabel])
        self.__dictionary=""
        self.__poolcontainer=""
        self.__defaultXMLheader="\n".join([
            "<?xml version=\'1.0\' encoding=\"UTF-8\"?>",
            "<!DOCTYPE PoolDatabase SYSTEM \"InMemory\">",
            "<PoolDatabase>",
            "<PoolContainer name=\"##CONTAINERNAME##\" tech=\"homogeneous\" >",
            "<Class name=\"##CLASSNAME##\" mapping_version=\"##MAPPINGVERSION##\">",
            "</Class>",
            "</PoolContainer>",
            "</PoolDatabase>"])
        self.__defaultXMLheader=self.__defaultXMLheader
    def buildtempxml(self,classname):
        self.__defaultXMLheader=self.__defaultXMLheader.replace("##CONTAINERNAME##",self.__poolcontainer)
        self.__defaultXMLheader=self.__defaultXMLheader.replace("##CLASSNAME##",classname)
        self.__defaultXMLheader=self.__defaultXMLheader.replace("##MAPPINGVERSION##",self.__mappingversion)

    def parseclassdefxml(self,classname):
        """
        Parse classes_def.xml to get parameter
        self.__classname
        and default values of
        self.__poolcontainer
        self.__dictionary 
        """
        self.__poolcontainer=self.__classname
        print "poolcontainer ",self.__poolcontainer
        f=open(os.path.join(self.__path,"classes_def.xml"),'r')
        searchfor="class name=\""+classname+"\""
        for line in f:
            pos=line.find(searchfor)
            if pos>0: #found line
                fields=line.split(' ')
                #print fields
                for field in fields:
                    if field.find("class_version") != -1:
                        result=field.split("\"")[1]
                        self.__classversion=result
                        print "result",result
        f.close()
        
    def parsecmdln(self):
        """
        Parse commandline
        """
        usage = "usage: \%prog [options] \n"
        parser = OptionParser()
        parser.add_option("-c","--classname",action="store",dest="classname",
                          help="class to generate mapping (required)")
        parser.add_option("-P","--Path",action="store",dest="path",
                          help="path to file classes_def.xml( required )")
        parser.add_option("-m","--mappingversion",action="store",dest="mappingversion",
                          help="mappingversion associated with this class version(default to automatic_default)")        
        parser.add_option("-d","--dictionary",action="store",dest="dictionary",
                          help="dictionary(default is deduced from class_def.xml directory SubsystemNamePackageName)")
        parser.add_option("-v","--verbose",action="store_true",dest="verbose",
                          help="verbose mode")

        (options, args) = parser.parse_args()
        self.__classname=options.classname
        self.__path=os.path.abspath(options.path)
        if options.mappingversion:
            self.__mappinglabel=options.mappingversion
        self.__mappingversion="_".join([self.__classname, self.__mappinglabel])
        self.parseclassdefxml(self.__classname)
        if options.dictionary:
            self.__dictionary=options.dictionary
        else:
            parent=os.path.split(self.__path)[0]
            pkg=os.path.split(parent)[1]
            subsys=os.path.split(parent)[0]
            subsys=os.path.split(subsys)[1]
            self.__dictionary=subsys+pkg
            #print self.__dictionary
        self.__verbose=options.verbose
        self.buildtempxml(self.__classname)
        if self.__verbose is True:
            print "classname : %s " % self.__classname
            print "classversion : %s " % self.__classversion
            print "poolcontainer : %s " % self.__poolcontainer
            print "mappingversion : %s " % self.__mappingversion
            
    def generate(self):
        '''create xml catalog with given input
        '''        
        outfilename=self.__mappingversion+"_"+self.__classversion+".xml"
        f = open('temp.xml','w')
        f.write(self.__defaultXMLheader)
        f.close()
        if self.__verbose is False:
            cmd=' '.join(['pool_build_object_relational_mapping','-c','sqlite_file:dummy.db','-dry','-d',self.__dictionary,'-f','temp.xml','-o',outfilename])
        else:
            cmd=' '.join(['pool_build_object_relational_mapping','-c','sqlite_file:dummy.db','-dry','-d',self.__dictionary,'-f','temp.xml','-o',outfilename])
        os.system(cmd)
        os.remove('temp.xml')
        os.remove('dummy.db')
if __name__ == "__main__":
    me=mappingGenerator()    
    me.parsecmdln()
    me.generate()


