#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Classes and functions for configuration file handling
"""

import sys 
import re
import resource
import directive


RESOURCE_TYPES = ('dird', 'console', 'filed', 'stored')

rxp_item = re.compile('^\\s*(\\w[\\w ]*\\w+)\\s*\\=(.*)') # xxx = xxx matchen
rxp_item2 = re.compile('^\\s*(\\w[\\w ]*\\w+)\\s*\\=\\s*{(.*)}\\s*') # match type = { a = 1; b= 2}
rxp_openbrace = re.compile('^\\s*(\\w[\\w ]*\\w+)\\s*\\=?\\s*\\{\\s*')    # match xxx {
rxp_open = re.compile('^\\s*(\\w[\\w ]*\\w+)\\s*$')    # match xxx 
rxp_closebrace = re.compile('[^{]*}.*')               # match }
rxp_comment = re.compile('^\s*#.*')


currentConfig = None

#'dird', 'console', 'filed' or 'stored'
class Config(object):
    """Class for bacula configuration access"""
    
    def __init__(self, resource_type, filename=""):
        self.resource_type = resource_type
        self.filename = filename
        self.resources = resource.Root(level=0)
        self.resources.type="<root>"

    def read(self):
        self.parse(self.resources,open(self.filename,"r"),0)
        #print self.resources
        
    def write(self, filename=None):
        if(filename==None):
            filename=self.filename
        f=open(filename,"w")
        f.write(str(self.getRoot()))
        f.close()

    def getRoot(self):
        return self.resources

    def addResource(self,resname,level,curRes):
        try:
                resClass = getattr(resource,resname);
        except:
                resClass = resource.Resource

        newRes=resClass(level+1)
        newRes.type=resname
        curRes.add_item(newRes);
        return newRes

    def parse(self,curRes,f,level):
        #print "START",curRes.type

        while True:
            line=f.readline()
            if not line:
                break

            inlinecomment=None
         
            commentStart=line.find("#")
            if commentStart!=-1:
                inlinecomment=line[commentStart:]
                line=line[:commentStart].strip()
                #curRes.add_comment(inlinecomment)

            include=line.strip()
            if include.startswith("@"):
                includepath=include[1:].strip()
                print "include " +includepath
                self.parse(curRes,open(includepath,"r"),level)

            if rxp_closebrace.match(line):
                #print "closebraceline"
                break

            item2 = rxp_item2.match(line)
            if item2:
                #print "item2"
                name = item2.group(1)
                value = item2.group(2)
                #print "item:",name,value
                newRes=resource.Resource(level+1)
                newRes.type=name
                newRes.value="{"+value+"}"
                curRes.add_item(newRes)
                continue

            openbraceline = rxp_openbrace.match(line)
            if openbraceline:
                #print "openbraceline"
                resname = openbraceline.group(1)
                newRes=self.addResource(resname,level,curRes)
                self.parse(newRes,f,level+1);
                continue

            open = rxp_open.match(line)
            if open:
                resname = open.group(1)
                newRes=self.addResource(resname,level,curRes)
                self.parse(newRes,f,level+1);
                continue

            item = rxp_item.match(line)
            if item:
                name = item.group(1)
                value = item.group(2).strip()
                #print "item:",name,value
                newRes=resource.Resource(level+1)
                newRes.type=name
                newRes.value=value
                curRes.add_item(newRes)
                continue

        #print "END",curRes.name
    
class DirdConfig(Config):
    
    def __init__(self, filename=""):
        Config.__init__(self, 'dird', filename)
        
class ConsoleConfig(Config):
    pass

class FiledConfig(Config):
    def __init__(self, filename=""):
        Config.__init__(self, 'fd', filename)

    def setDefaults(self,directorName,directorPassword,myName):
        director=resource.Director(1,"Director")
        director.add("Name",directorName)
        director.add("Password",'"'+directorPassword+'"')
        self.getRoot().add_item(director)
        
        fileDaemon=resource.FileDaemon(1,"FileDaemon")
        fileDaemon.add("Name",myName)
        #fileDaemon.add("FDport","9102")
        fileDaemon.add("WorkingDirectory","/var/lib/bacula")
        fileDaemon.add("Pid Directory","/var/run")
        fileDaemon.add("Maximum Concurrent Jobs","20")
        self.getRoot().add_item(fileDaemon)

        messages=resource.Messages(1,"Messages")
        messages.add("Name","Standard")
        messages.add("director",directorName+" = all, !skipped, !restored")
        self.getRoot().add_item(messages)
        
class StoredConfig(Config):
    pass

#
# nur zum Testen
from VanHelsingWrapper import *

if __name__ == "__main__":
    if len(sys.argv) < 2:
        filename="test.conf"
    else:
        filename=sys.argv[1]   

    loadDirectorConfig(filename)
    #testweise, damit man mal nachvollziehen kann, welche Funktion was ausspuckt
    print "getClients(\"bacula-dir\")"
    print getClients("bacula-dir")
  
    print "getResources(\"bacula-dir\",\"Client\")"
    print getResources("bacula-dir","Client")
    
    print "getResources(\"bacula-dir\",\"Job\")"
    print getResources("bacula-dir","Job")

    print "getResourceById(\"bacula-dir\",54)"
    print getResourceById("bacula-dir",54)

    print "getResourceByName(\"Bacula-dir\",\"Job\",\"meinBackup\")"
    print getResourceByName("Bacula-dir","Job","meinBackup")
    sys.exit(0)
