import ConfigParser
import os
import logging

from common import exception

class Configuration(object):

    type = None

    def __init__(self, cf=""):
        self.cfg = ConfigParser.ConfigParser()
        self.configFiles = [cf, '/etc/se.conf', 'se.conf']
        files = self.cfg.read(self.configFiles)
        
        if files == None:
            raise Exception("Configuration file not found.")

    def get(self, key, default=None, check=None):
        try:
            ret = self.cfg.get(self.type, key)
        except (ConfigParser.NoSectionError, ConfigParser.NoOptionError), e:
            if default != None:
                ret = default
            else:
                s = "Missing Configuration Item: Secion %s, Option %s"
                raise exception.ConfigurationError(s % (self.type, key))

        if check:
            check(ret)

        return ret

    def record(self, key, value):
        self.cfg.set(self.type, key, value)

        for file in self.configFiles:
            if os.access(file, os.W_OK):
                fd = open(file, 'w')
                self.cfg.write(fd)
                fd.close()
                logging.getLogger().info("Wrote config file: %s" % file)
                return

        raise exception.ConfigurationError(     \
                "Could not save %s=%s in configuration file" % (key, value))

    def checkFile(self, file, message="Bad file %s"):
        if not os.access(file, os.R_OK):
            raise exception.ConfigurationError(message % file)
    

class Logger(Configuration):

    _logConfigured = False
    
    def __init__(self, cf=""):
        Configuration.__init__(self, cf)

        if self._logConfigured: return

        file = self.get("logfile", default="")
        level = int(self.get("loglevel", default="0"))
        
        logger = logging.getLogger()
        if file == "":
            handler = logging.StreamHandler()
        else:
            if os.access(file, os.W_OK):
                handler = logging.FileHandler(file)
            else:
                raise exception.ConfigurationError(  \
                        "Cannot write to log file %s" % file )

        formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        logger.setLevel(level)

        logger.info("Logging initialized.")
        Logger._logConfigured = True
        
        
class CA(Configuration):

    type = None

    def getCert(self):
        return self.get("cert", check=self.checkFile)

    def getCA(self):
        return self.get("ca", check=self.checkFile)
    
    def getPeer(self):
        return self.get("peer_ca", check=self.checkFile)


class Client(CA, Logger):

    type = "client"

    def getUID(self):
        uuid = self.get("uuid", default="")
        return uuid

    def setUID(self, uuid):
        self.record("uuid", uuid)

    def getServer(self):
        return self.get("server")
    

class Server(CA, Logger):

    type = "server"
   
    def getDBType(self):
        return self.get("db_type")

    def DBFile(self):
        return self.get("db")

    def ConfigDir(self):
        return self.get("configs")

    def getSecret(self):
        return self.get("secret", default="StateEngine Secret")

