#!/usr/bin/env python
import os
from ConfigParser import ConfigParser
from copy import copy
from optparse import OptionParser, Option, OptionValueError
import coral
from CondCore.TagCollection import Node,tagInventory,CommonUtils,entryComment
def stripws(myinput):
    result=('').join(myinput.split(' '))
    result=('').join(result.split('\n'))
    return result
def converttagdata(value):
    mytagdata={}
    startbrack=value.find('{')
    endbrack=value.find('}')
    metadatastr=value[startbrack+1:endbrack]
    mytagdata['tagname']=value[0:startbrack]
    metadatalist=metadatastr.split(',')
    for pair in metadatalist:
        mydata=pair.split('=',1)
        mytagdata[mydata[0]]=mydata[1]
    return mytagdata
def converttagcollection(value):
    cleanvalue=stripws(value)
    mytagcollection=[]
    taglist=cleanvalue.split(';')
    for tagdata in taglist:
        mytagcollection.append(converttagdata(tagdata))
    return mytagcollection
def check_tagdata(option, opt, value):
    try:
        return converttagcollection(value)
    except ValueError:
        raise OptionValueError(
            "option %s: invalid tagdata: %r" % (opt, value))
class MyOption (Option):
    TYPES = Option.TYPES + ("tagdata",)
    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
    TYPE_CHECKER["tagdata"] = check_tagdata
    
class tagInventoryBuilder:
    def __init__(self):
        """
        Class add entry in the tag inventory
        usage: %prog [options]
        -f, --file=filename: configuration file. -t will not be considered together with the -f option. The connect parameter will be overwritten by option -c.
        -c, --connect=connectstring: connection string to the tag DB. If -c, -f both given -c value will overwrite the connect parameter in the config file. 
        -u, --user=user: user name
        -p, --password=password: password
        -P, --path=path: path to authentication.xml
        -t, --tag=tagdata: \"tag1{pfn=string,objectname=string, recordname=string, labelname=string};tag2{...}\"
        -v, --verbose: switch on verbose mode
        -h, --help: print usage
        """
        self.__parser=OptionParser(option_class=MyOption)
        self.__connectstring=''
        self.__user=''
        self.__password=''
        self.__authpath=''
        self.__tagcollection=[]
        self.__verbose=False
    def parsecmdln(self):
        """
        Parse commandline
        """
        usage = "usage: \%prog [options] \n"
        self.__parser.add_option("-f","--file",action="store",dest="filename",help="populate the inventory from the given file. -t will not be considered together with the -f option. The connect parameter will be overwritten by option -c.")
        self.__parser.add_option("-c","--connect",action="store",dest="connectstring",type="string",help="connection string to the tag DB. If -c, -f both given -c value will overwrite the connect parameter in the config file.")
        self.__parser.add_option("-u","--user",action="store",dest="user",type="string",help="user name")
        self.__parser.add_option("-p","--password",action="store",dest="password",type="string",help="password")
        self.__parser.add_option("-P","--path",action="store",dest="authpath",type="string",help="path to authentication.xml")
        self.__parser.add_option("-t","--tagdata",action="store",dest="tagdata",type="tagdata",help=" \"tagname{pfn:string,objectname:string,recordname:string, labelname:string}\" ")
        self.__parser.add_option("-v","--verbose",action="store_true",dest="verbose",help="verbose mode")
        self.__parser.set_defaults(filename='')
        self.__parser.set_defaults(connectstring='')
        self.__parser.set_defaults(user='')
        self.__parser.set_defaults(password='')
        self.__parser.set_defaults(authpath='.')
        self.__parser.set_defaults(tagdata=[])
        self.__parser.set_defaults(verbose=False)
        (options, args) = self.__parser.parse_args()
        if options.filename and options.connectstring:
            print 'Warning: -c option ',options.connectstring, 'overwrites the connection string in ',options.filename
            #raise OptionValueError("option -%s and -%s are exclusive"%('f','c'))
        if len(self.__parser.values.authpath)!=0:
            self.__authpath=self.__parser.values.authpath
        else:
            self.__user=self.__parser.values.user
            self.__password=self.__parser.values.password
        self.__verbose=self.__parser.values.verbose
        if self.__parser.values.filename!='':
            configparser=ConfigParser()
            configparser.read(self.__parser.values.filename)
            if options.connectstring:
                self.__connectstring=self.__parser.values.connectstring
            else:
                self.__connectstring=configparser.get("COMMON","connect")
            data=stripws(configparser.get("TAGINVENTORY",'tagdata'))
            self.__tagcollection=converttagcollection(data)
            if self.__parser.values.verbose is True:
                print 'config file: ',self.__parser.values.filename
        else:
            self.__connectstring=self.__parser.values.connectstring
            data=stripws(self.__parser.values.tagdata)
            self.__tagcollection=converttagcollection(data)
        if self.__parser.values.verbose is True:
            print 'connectstring: ',self.__connectstring
            print 'user: ',self.__user
            print 'password: ',self.__password
            print 'authpath: ',self.__authpath
            print 'tagdata: ',self.__tagcollection
    def addEntries(self):
        """
        Add entries in the tag inventory
        """
        #context = coral.Context()
        #if self.__verbose is True:
        #    context.setVerbosityLevel( 'DEBUG' )
        #else:
        #    context.setVerbosityLevel( 'ERROR' )
        svc = coral.ConnectionService()
        config=svc.configuration()
        os.environ['CORAL_AUTH_PATH']=self.__authpath
        config.setDefaultAuthenticationService('CORAL/Services/XMLAuthenticationService')
        session = svc.connect( self.__connectstring,accessMode = coral.access_Update )
        try:
            inv=tagInventory.tagInventory(session)
            #print 'about to create table'
            if inv.existInventoryTable() is False:
                inv.createInventoryTable()
            if len(self.__tagcollection)!=0:
                for item in self.__tagcollection:
                    tagentry=Node.LeafNode()
                    tagentry.tagname=item['tagname']
                    tagentry.objectname=item['objectname']
                    tagentry.pfn=item['pfn']
                    tagentry.recordname=item['recordname']
                    if item.has_key('labelname'):
                        tagentry.labelname=item['labelname']
                    else:
                        tagentry.labelname=''
                    tagid=inv.addEntry(tagentry)
                    if item.has_key('comment'):
                        entrycomment=entryComment.entryComment(session)
                        if entrycomment.existCommentTable() is False:
                            entrycomment.createEntryCommentTable()
                        entrycomment.insertComment(CommonUtils.inventoryTableName(),tagid,item['comment'])
            del session
        except Exception, e:
            print str(e)
            del session        
if __name__ == "__main__":
    tagbuilder=tagInventoryBuilder() 
    tagbuilder.parsecmdln()
    tagbuilder.addEntries()

