# -*- coding: utf-8 -*-
# $Id: config_classes.py 12290 2011-02-10 14:02:38Z pstorz $
import re
import logging
import copy
logger = logging.getLogger("directive")
import scheduleparser # schedule class
from auto_types import *

from  prettynames import *

RXP_SIMPLE_ITEM = re.compile(r'''
(^|;)(\s*(?P<itemname>[\w ]+?)?\s*=\s*(?P<value>"?[^;^\n]+"?)(?P<comment>\s+\#.*)?) # xxx = yyy # comment
''',re.M| re.X) 
#(^|;)(\s*(?P<itemname>[\w ]+?)?\s*=\s*(?P<value>"?[^{^}^;^\n]+"?)(?P<comment>\s+\#.*)?) # xxx = yyy # comment
   
#(^|;)(\s*(?P<itemname>[\w ]+?)?\s*=\s*(?P<value>"?[^{^}^;^\n^\s]+"?)\s*(?P<comment>\s+\#.*)?) # xxx = yyy # comment

RXP_RESTYPE = re.compile(r'''
  ^\s*(?P<resourcetype>\w[\w ]+?\s*(=\s+)?\s?)$
''', re.M|re.X|re.S)

# TODO: allow spaces in resourcetypes like sd addresses! 
# this does not work now 
#  SD Addresses = <
 
RXP_NRTEXT = re.compile(r'''
(?P<number>\d+)\s?(?P<text>[A-Za-z]+)
''', re.M|re.X|re.S)

#RXP_TEXTNR = re.compile(r'''
#(?P<text>\w+)\s?(?P<number>\d+)
#''', re.M|re.X|re.S)

# what resources can appear multiple times in director configs?
MULTIPLE_RESOURCES_IN_DIRD = set([
                                  'client',
                                  'console',
                                  'fileset',
                                  'job',
                                  'jobdefs',
                                  'messages',
                                  'pool',
                                  'schedule',
                                  'storage', 
                                  ])

INTERNALLY_REFERENCED_ITEMS = set(['fileset',
                                  'client' ,
                                  'catalog',
                                  'messages',
                                  'schedule',
                                  'storage',
                                  'jobdefs',
                                  'pool',
                                  'incrementalbackuppool',
                                  'fullbackuppool',
                                  'differentialbackuppool',
                                  'job',
                                  'basejob',
                                  'device',
                                  ])

# translate full name to short name
res2shrtn = {          'catalog'      :'cat', 
                       'client'       :'cli',
                       'console'      :'con',
                       'counter'      :'counter',
                       'director'     :'dir',
                       'fileset'      :'fs',
                       'filedaemon'   :'cli',  # filedaemon is the same as cli
                       'job'          :'job',
                       'jobdefs'      :'job',  # jobdefs are the same as jobs
                       'messages'     :'msgs',
                       'pool'         :'pool',
                       'runscript'    :'runscript',
                       'schedule'     :'sch',
                       'storage'      :'store',
                       #'console'      :'con',
                       'autochanger'  :'changer',
                       'device'       :'dev',     
                      'options'       :'options',
                       #manually added
                      'diraddresses'  :'addresses',
                      'fdaddresses'  :'addresses',
                      'sdaddresses'  :'addresses',
                      'ip'           :'ip',
                      'ipv4'         :'ip',
                      'ipv6'         :'ip',
                      'include'      : 'include',
                      'exclude'      : 'include',
                       }


# which itemsnames can appear multiple times?
MULTIPLE_ALLOWED_ITEMS_SET  = set([
                             'file', 
                             'run',
                             ])

#MULTIPLE_ALLOWED_RESOURCES_SET = set([
#                                      'include',
#                                      'exclude',
#                                      'ip',
#                                      ])


timemultiplicators = { 
               "seconds"  : 1, 
               "minutes"  : 60,
               "mins"     : 60,
               "hours"    : 3600,
               "days"     : 3600*24, 
               "weeks"    : 3600*24*7,   
               "quarters" : 3600*24*91,   
               "years"    : 3600*24*365,
               "months"   : 60*60*24*30,
               "n"        : 60,
               }

datamultiplicators  = { 
                "k" : 1024,          #/* kilobyte */
                "kb": 1000,          #/* kb kilobyte */
                "m" : 1048576,       #/* megabyte */
                "mb": 1000000,       #/* mb megabyte */ 
                "g" : 1073741824,    #/* gigabyte */
                "gb": 1000000000};   #/* gb gigabyte */
                

RESSOURCES_WITH_EQUALSIGN = set(['diraddresses',
                                'fdaddresses',
                                'sdaddresses',
                                'ip',
                                'ipv4',
                                'ipv6',
                                ])

#INDENTSTRING = '|--|'
INDENTSTRING = '  '




class Item(object):
    def __init__(self, name, value, defaultvalue, default, type, required, parentresource = None, indentlevel = 0):
        self.indentlevel = indentlevel
        self.parentresource = parentresource
        self.name = name.lower().replace(' ','')
        self.defaultvalue = defaultvalue
        self.default = default
        self.value = value # real value lies in storage        
        self.type = type
        self.required = required
        self.printall = False
        #TODO: try/except this eval
        #print type, defaultvalue
        
        #storage1 = eval(type + '(' + str(defaultvalue) +')' )
        #self.storage = copy.deepcopy(storage1)
        #logger.debug('storage: ' +str(id(self.storage)) + ' storage1: ' + str(id(storage1)))
        
        self.storage  =  eval(type + '(' + str(defaultvalue) +')' )
        self.storage.setValue(value)
        
        
        self.storage.indentlevel = self.indentlevel + 1
        self.storage.setParentItem(self)
  

    def __lt__(self,other):
      #print "comparing", self.name, other.name
      if self.name == 'name': # name comes first
        #print self.name,"<",other.name
        return True
      if self.name < other.name :
        #print self.name,"<",other.name
        return True
      else:
        #print self.name,">",other.name
        return False


    def __repr__(self):
      string_types = set(['store_time'])
      if self.type in string_types: # explicitly store this in a string
          return "Item(\'%s\', \'%s\', \'%s\', %s, \'%s\', %s)" % (str(self.name),
                                                         self.value,
                                                         self.defaultvalue,
                                                         self.default,
                                                         str(self.type),
                                                         self.required)
      else:
          return "Item(\'%s\', %s, %s, %s, \'%s\', %s)" % (str(self.name),
                                                         self.value,
                                                         self.defaultvalue,
                                                         self.default,
                                                         str(self.type),
                                                         self.required)


    ''' find out if this item is to be printed or not '''
    def print_item(self):
        printout = self.printall # override to print all out        
        if self.default:
          if str(self.storage.value) != str(self.defaultvalue):
            logger.debug( "printing " + self.name + " as self.storage.value != self.defaultvalue:"
                         + str(self.storage.value) + ' != ' + str(self.defaultvalue) + '<' )
            printout = True
          else:
            #pass
            logger.debug( "NOT printing " + self.name + " as self.storage.value == self.defaultvalue:"
                         + str(self.storage.value) + ' == ' + str(self.defaultvalue) + '<' )

        elif self.required:
          # jobs can inherit their items from jobdefs, jobdefs do not need a client
          # but a name is needed anyway
          # TODO: merge jobs and jobdefs in order to check if they are complete after merge

          # jobs and jobdefs
          if self.parentresource.resourcetype.startswith('job') and self.value == self.defaultvalue and str(self.storage.value) == str(self.defaultvalue):
            printout = False
          else:
            logger.debug( "printing " + self.name + " as self.required is set")
            printout = True

        elif self.storage.value is not None:

          if self.storage.value != self.defaultvalue:
            logger.debug( "printing " + self.name + " as self.storage.value is set to :>"
                         + str( self.storage.value )+'<')
            printout = True

        return printout


    def __str__(self):
        '''
        standard behaviour: 
        only print items that are configured and have not a different value than the default value 
        '''

        if self.print_item():
          return '%s%s = %s\n' % ( self.indentlevel * INDENTSTRING,  prettyName(self.name), self.storage)
          #return '    %s = %s\n' % (prettyName(self.name), self.storage)
        else:
          return ''

    def setValue(self, value):
      '''set value item'''
      self.storage.setValue(value)





#class command(object):
#  '''
#  this class contains the information to a console command, also dot commands
#  '''
#  def __init__(self, commandtext, commandname, usage, help, inrunscript):
#    self.commandtext = commandtext
#    self.commandname = commandname
#    self.usage = usage
#    self.help = help
#    self.inrunscript = inrunscript
#
#  def __repr__(self):
#    return "command('%s','%s','%s','%s','%s')" % (self.commandtext, self.commandname, self.usage, self.help, self.inrunscript)




# the bacula internal storage representations
#
# base classes for all storages
class Item_Storage(object):
  """
  base class for the representation of any item object
  """
  
  def __init__(self,val):
    self.value = val
    self.comment = ''
    self.possiblevalues = []  # what values are possible here ?
    self.parentitem = None
    
  def __str__(self): 
    #TODO do this in a nicer way without a catch-all try-except
    if self.comment != '':
      comment = "\t# " + self.comment
    else:
      comment = '' 
    try:
      #return self.value 
      return self.value + comment #+self.__class__.__name__ + ' id: '+ str(id(self))
    except:
      #return str(self.value) 
      return unicode(self.value) + comment  #+self.__class__.__name__ + ' id: '+ str(id(self))
    
  def setParentItem(self,parentItem):
    self.parentitem = parentItem
    
  def setValue(self,value):
    logger.debug( self.__class__.__name__ +':' + 'called self.value with \''+ str(value) + '\'')    
    self.value = value
    logger.debug("self.value is now" + str(self) )

class Item_Storage_String (Item_Storage):
  pass
    #def __str__(self):
    #  return str(self.value)
      #return '"' + str(self.value) + '"'# + '\t# '+ self.__class__.__name__


# generated
class store_pint32( Item_Storage ): 
  def __str__(self):
    return str(self.value) #+ '\t# '+self.__class__.__name__ + 'id: '+ str(id(self))
    #return str(self.value) + '\t# '+self.__class__.__name__ + 'id: '+ str(id(self))
                   

                   

class store_name( Item_Storage_String ):
  
  def setValue(self,value):
    logger.debug( self.__class__.__name__ +':' + 'called self.value with \''+ unicode(value) + '\'')   
    if value != None  and value != 0:
      if type(value) == str: 
        value = value.strip('"')
      else:
        value = str(value)
      self.value = '"' + value.strip('"') + '"'
    else:
      self.value = value
    logger.debug("self.value is now " + unicode(self) )
                            

class store_str( store_name ):
  pass                          

class store_time( Item_Storage ):                         
  def __init__(self,val):
    self.value = val
    self.comment = ''
    self.possiblevalues = []  # what values are possible here ?
    self.parentitem = None
    
  def __str__(self): 
    #TODO do this in a nicer way without a catch-all try-except
    if self.value is None:
      return str(self.value)
    outstring = ''
    for mult in ["years", "quarters" ,"months" ,"weeks", "days","hours","minutes","seconds"]:
      if self.value % timemultiplicators[mult] == 0:
        outstring = "%d %s " % (self.value/timemultiplicators[mult], mult)
        return outstring    
    return outstring  
    
  def setParentItem(self,parentItem):
    self.parentitem = parentItem
    
  def setValue(self,value):
    logger.debug( self.__class__.__name__ +':' + 'called self.value with \''+ str(value) + '\'')    
    self.value = self.__parse_timeinput__(value)
    logger.debug("self.value is now" + str(self) )
  
  def __partNumberKeywords__(self,string):
    '''
    inserts a space between numbers and keywords if there is none
    '''
    return re.sub(r'([0-9](?=[A-Za-z])|[A-Za-z](?=[0-9]))', "\\1 ", string)
    #s = ''
    #for match in RXP_NRTEXT.finditer(string):
    #  #print string,match.groups()
    #  s += ' '.join(match.groups()) + ' '
    #return s
  
  def __parse_timeinput__(self,timestring):
    '''
    parses the input string and sets the value to the resulting seconds 
    '''
    timeval = 0
    if timestring is None or timestring == 'None':
      return None
    multiplicator = 1
    # search for x*x*X*X...
    index = timestring.find('*')
    if index != -1:
      timeval = eval(timestring)
      #print timeval
      return timeval
      #timestring = str(timeval)
      
    
    if  timestring.isdigit():
      return int(timestring)
    
    
    # search for multiple pairs like "3 seconds 4 days"
    timestring = self.__partNumberKeywords__(timestring)
    valueUnitPairs = timestring.split()
    valueUnitPairs.reverse()
    #print valueUnitPairs
    #print timestring+'<'
    if len(valueUnitPairs)%2:
      logger.error(valueUnitPairs)
      logger.error("There should always be a pair of value-unit\n maybe you forgot a space between value and unit?")
    while len(valueUnitPairs) > 1:
      vustr = str(valueUnitPairs.pop()) + ' ' + str(valueUnitPairs.pop())
      for cut in (range(8)):
        if cut == 0: # extra, as range -0 leads to nothing instead of giving the whole string
          cut = -8
        for mult in ('months','seconds',
                 'mins','minutes','hours',
                 'days','weeks','quarters',
                 'years'):        #,'n'      
          index = vustr.lower().find(mult[:-cut])
          #print mult[:-cut],vustr
          if  index != -1 and len(mult[:-cut])>0:
            multiplicator = timemultiplicators[mult]
            tmpstring = vustr.replace(mult[:-cut],'')
            #print mult[:-cut],vustr
            vustr = tmpstring
          
      timeval += float(vustr) * multiplicator   
      #print "%s -> %d " % (vustr,timeval)
    
    
    return int(timeval)




class store_bool( Item_Storage ):      
  #pass
  '''
  also base class for store_bit
  '''
  
  def __init__(self,val):
    Item_Storage.__init__(self, val)
    self.setValue(val)
   
  def setValue(self,value):
    logger.debug( self.__class__.__name__ +':' + 'called self.value with \''+ str(value) + '\' type: ' + str(type(value)))    
    if type(value) is str:
      logger.debug('value was string')
      if value.lower() == 'yes' or value.lower() == '1':
        self.value = True
      else:
        self.value = False   
        
    elif type(value) is int: # type int
      logger.debug('value was int')
      if value == 1:
        self.value = True
      else:
        self.value = False
        
    elif type(value) is bool: # type int
      logger.debug('value was bool')
      self.value = value    
    else:
      logger.error( "value must be <int> or <str>, but is " + str(type(value)) )

    logger.debug('value is now ' + str(self.value))
  
  def __str__(self):
    if self.comment != '':
      comment = "\t# " + self.comment
    else:
      comment = '' 
    if self.value == True: 
      #return 'Yes'#+ '\t# '+self.__class__.__name__ + 'id: '+ str(id(self))
      return 'Yes'  + comment  #+self.__class__.__name__ + 'id: '+ str(id(self))
    
    else:
      #return 'No' #+ '\t# '+self.__class__.__name__  + 'id: '+ str(id(self))
      return 'No'  + comment  #+self.__class__.__name__  + 'id: '+ str(id(self))   

class store_bit( store_bool ):
  pass       


class store_dir( store_name ):      
  pass


class store_alist_str( Item_Storage_String ):
  pass     

class store_password( store_name ):
  pass                               

class store_res( Item_Storage_String ):
  pass                          



class store_acl( Item_Storage_String ):
    
  def __init__(self,val):
    self.value = val
    self.comment = ''
    self.possiblevalues = []  # what values are possible here ?
    self.parentitem = None
    self.ACLDict = {}
    
  def __str__(self):
    return str(self.value)
  
    
  def setParentItem(self,parentItem):
    self.parentitem = parentItem
    
  def setValue(self,value):
    logger.debug( self.__class__.__name__ +':' + 'called self.setvalue with \''+ str(value) + '\'')
    self.value = value
    self.__Value2ACLDict__()
    self.__ACLDict2value__()
    #self.__parse_ACLinput__(value)
    #self.ACLDict2value()
    logger.debug("self.value is now >%s<" %( self.value ))
  
  def __Value2ACLDict__(self):
    '''
    parses the input string and sets the ACL Dictionary 
    '''
    #print "parsing the following value: %s  " % (self.value)
  
    if self.value is None or self.value == 'None' or self.value == u'' or self.value == '':
      for k in self.ACLDict.keys():
        self.ACLDict[k]= False
      self.value = None
    else:
      for acl in self.value.replace(' ','').split(','):
        self.ACLDict[acl]=True
    self.__ACLDict2value__()
    #print self.ACLDict
    
  
  def __ACLDict2value__(self):
    '''
    reads the acl Dictionary and produces the correct output in the value field
    '''
    s = ''

    for msg,val in self.ACLDict.iteritems():    
      if val == True:
        s += '%s,' % (msg)
    #self.setValue(s[:-1])
    #self.value = s[:-1]
    if (len(s[:-1])) == 0:
      self.value = None
    else:
      self.value = s[:-1]# cut last comma
    

  





class store_int32( Item_Storage ):
  pass                            

class store_addresses_port( Item_Storage ):
  pass                                     

class store_addresses( Item_Storage ):
  pass                                      

class store_addresses_address( Item_Storage ):
  pass
 
class store_inc( Item_Storage ):
  pass                          

class store_migtype( Item_Storage ):
  
  def __init__(self,val):
    Item_Storage.__init__(self, val)
    self.possiblevalues = migtypes             
    if val == 0:
      Item_Storage.setValue(self,  'smallestvolume')   
    
class store_short_runscript( Item_Storage ):
  pass                                      

class store_runscript( Item_Storage ):
  pass                                

class store_alist_res( Item_Storage_String ):
  pass                                

class store_jobtype( Item_Storage ):
  
  def __init__(self,val):
    Item_Storage.__init__(self, val)
    self.possiblevalues = jobtypes
    if val == 0:
      Item_Storage.setValue(self,  'backup')

class store_replace( Item_Storage ):
  
  def __init__(self,val):
    Item_Storage.__init__(self, val)
    self.possiblevalues = ReplaceOptions
    if val == 0:
      Item_Storage.setValue(self,  'always')

class store_level( Item_Storage ):
  
  def __init__(self,val):
    Item_Storage.__init__(self, val)
    self.possiblevalues = joblevels
    if val == 0:
      Item_Storage.setValue(self,  'full')    


class store_size64( Item_Storage ):
  def __init__(self,val):
    self.value = val
    self.comment = ''
    self.possiblevalues = []  # what values are possible here ?
    self.parentitem = None
    
  def __str__(self): 
    #TODO do this in a nicer way without a catch-all try-except
    if self.value is None:
      return str(self.value)
    outstring = ''
    for mult in ["gb","mb","kb","g","m","k"]:
      if self.value % datamultiplicators[mult] == 0:
        outstring = "%d %s " % (self.value/datamultiplicators[mult], mult)
        return outstring    
    return str(self.value)
    
    #outstring = ''
    #for mult in ["years", "quarters" ,"months" ,"weeks", "days","hours","minutes","seconds"]:
    #  if self.value % timemultiplicators[mult] == 0:
    #    outstring = "%d %s " % (self.value/timemultiplicators[mult], mult)
    #    return outstring    
    #return outstring  
    
  def setParentItem(self,parentItem):
    self.parentitem = parentItem
    
  def setValue(self,value):
    logger.debug( self.__class__.__name__ +':' + 'called self.value with \''+ str(value) + '\'')    
    self.value = self.__parse_datainput__(value)
    logger.debug("self.value is now" + str(self) )
  
  def __parse_datainput__(self,datastring):
    '''
    parses the input string and sets the value to the resulting seconds 
    '''
    if datastring is None or datastring == 'None':
      return None
    
    datastring = str(datastring).lower()
    
    multiplicator = 1
    dstring = datastring
    for mult in ["gb","mb","kb","g","m","k"]:
        index = dstring.lower().find(mult)
        if  index != -1:
          multiplicator = datamultiplicators[mult]
          tmpstring = datastring.replace(mult,'')
          #print datastring
          dstring = tmpstring
    dataval = float(dstring) * multiplicator   
    return dataval
    
        
    # search for x*x*X*X...
    #index = timestring.find('*')
    #if index != -1:
    #  timeval = eval(timestring)
    #  print timeval
    #  timestring = str(timeval)#####

    #print timestring+'<'
    #for mult in timemultiplicators:
    #  for cut in (range(8)):
    #    if cut == 0: # extra, as range -0 leads to nothing instead of giving the whole string
    #      cut = -8
    #    index = timestring.find(mult[:-cut])
    #    if  index != -1 and len(mult[:-cut])>0:
    #      multiplicator = timemultiplicators[mult]
    #      tmpstring = timestring.replace(mult[:-cut],'')
    #      #print timestring
    #      timestring = tmpstring
    #timeval = float(timestring) * multiplicator   
    #return timeval


class store_strname( Item_Storage_String ):
  pass

class store_label( Item_Storage_String ):
  pass

class store_actiononpurge( Item_Storage ):
  pass

class store_runscript_bool( Item_Storage ):
  pass

class store_runscript_cmd( Item_Storage ):
  pass

class store_runscript_target( Item_Storage ):
  pass

class store_runscript_when( Item_Storage ):
  pass

class store_run( Item_Storage_String ):
  def __init__(self,val):
    self.value = val
    logger.debug('store_run: called with ' + str(val))
    self.runentry = scheduleparser.RunEntry(val)
    self.possiblevalues = []
    
  def setValue(self,value):
    self.runentry.setValue(value)
    # set value to None if resutling string contains only whitespace,
    # in order to have the default value and not print it
    if len(str(self.runentry).strip()) == 0:
      self.value = None
    else:
      self.value = str(self.runentry)
    
     
  def __str__(self):
    self.value = str(self.runentry) # update value string
    return str(self.runentry)

class store_device( Item_Storage_String ):
  pass

class store_maxblocksize( Item_Storage ):
  pass

class store_devtype( Item_Storage ):
  pass



class store_msgs( Item_Storage ):
  
  def __init__(self,val):
    self.value = val
    self.comment = ''
    self.possiblevalues = []  # what values are possible here ?
    self.parentitem = None
    self.messageDict = {}
    self.parameter = None
    self.setValue(val)
    
  def __str__(self): 
    s = ''
      
    if self.parameter is not None:
      s += self.parameter + ' = '
      
    for msg,val in self.messageDict.iteritems():
      if msg == 'all':
        if self.messageDict['all']:
          s += 'all,'
        continue
    
      if self.messageDict['all']:
        if val == False:
          s += '!%s,' % (msg)
      else:# not all, so write all that are true
        if val == True:
          s += '%s,' % (msg)
    return s[:-1] # cut last comma
  
  def getParameter(self):
    '''
    this returns the target of the messages entry
    '''
    return self.parameter
  
  def setParameter(self, parameter):
    self.parameter = parameter
    
  def setParentItem(self,parentItem):
    self.parentitem = parentItem
    
  def setValue(self,value):
    logger.debug( self.__class__.__name__ +':' + 'called self.setvalue with \''+ str(value) + '\'')    
    self.value = self.__parse_messageinput__(value)
    logger.debug("self.value is now" + str(self) )
  
  def __parse_messageinput__(self,msgsstring):
    '''
    parses the input string and sets the value 
    '''
    if msgsstring is None or msgsstring == 'None':
      self.parameter = None
      return None
    
    splitted = msgsstring.split('=')   # do we have a message string with parameter 
    if len(splitted) > 1:                 # (like root@localhost = all, !skipped)
      self.parameter = splitted[0].rstrip(' ')
      msgsstring = splitted[1]
        
         
    messagestring = msgsstring.lower()
    for message in msg_types:
      self.messageDict[message] = None
      index = messagestring.find('!'+message)
      if  index != -1:
        logger.debug( "found NOT %s" % (message) )
        self.messageDict[message] = False  
      else:
        index = messagestring.find(message)
        if  index != -1:
          logger.debug("found %s" % (message))
          self.messageDict[message] = True  
    return self.__str__()

  
  
  
  
class store_opts( Item_Storage ):
  def __init__(self,val):
    Item_Storage.__init__(self, val)
    #if val == 0:
    #  Item_Storage.setValue(self,  'full')
  def setParentItem(self,parentItem):
    self.parentitem = parentItem
    try:
      self.possiblevalues =   FS_option_kw[self.parentitem.name]
      logger.debug(self.possiblevalues)
    except:
      logger.error('keyerror in FS_option_kw for ' + self.parentitem.name)
      

class store_drivetype( Item_Storage ):
  pass

class store_regex( Item_Storage ):
  pass

class store_wild( Item_Storage ):
  pass

class store_fstype( Item_Storage ):
  pass

class store_base( Item_Storage ):
  pass

class store_plugin( Item_Storage ):
  pass

class store_excludedir( Item_Storage ):
  pass

class store_fname( store_name ):
  pass


class options_res( Item_Storage ):
  pass


class store_plugin_name( Item_Storage ):
  pass



if __name__ == "__main__":
  #msgsstore = store_msgs("root@localhost = mount")
  tmp = store_time("1 hour")
  
  #for mult in ('months','seconds','n', 
  #               'mins','minutes','hours',
  #               'days','weeks','quarters',
  #               'years'):   
  #  for val in range(9):   
  #    value = str(val) + ' ' + mult
  #    tmp.setValue(value)
  #    print str(value) + '->'  +  str(tmp)
  #  
  tmp.setValue("1month30minutes12seconds")
  print tmp