#!/usr/bin/env jython

import sys
import os
import logging
from xml.etree.ElementTree import ElementTree, Element, tostring

from pslogger import PSLogger

'''
A class encapsulating the globald ippToPsps configuration information.
This is stored in the 'settings.xml' file in the config directory
'''
class Config(object):

    '''
    Constructor

    Basically reads the entire config and stores values to class variables
    '''
    def __init__(self):

        self.test = False
        self.resetDvo = False
        self.gpc1test = True
        self.retry = False
        self.camera = "gpc1"
        self.onebatch = False
        self.loopBatch = False

        if sys.argv.count("-test"):
            self.test = True
            sys.argv.remove("-test")

        if sys.argv.count("-t"):
            self.test = True
            sys.argv.remove("-t")

        # by default, we use gpc1test in a test, and do not if not a test
        self.gpc1test = self.test

        if sys.argv.count("-realgpc"):
            if not self.test:
                print "-realgpc requires -test"
                sys.exit(1)
            self.gpc1test = False
            sys.argv.remove("-realgpc")

        if sys.argv.count("-reset-dvo"):
            self.resetDvo = True
            sys.argv.remove("-reset-dvo")

        if sys.argv.count("-retry"):
            self.retry = True
            sys.argv.remove("-retry")

        if sys.argv.count("-simtest"):
            self.camera = "simtest"
            sys.argv.remove("-simtest")

        if sys.argv.count("-one-batch"):
            self.onebatch = True
            sys.argv.remove("-one-batch")

        if sys.argv.count("-loop"):
            self.loopBatch = True
            sys.argv.remove("-loop")

        ## name of the top-level jython script
        self.programName = os.path.basename(sys.argv[0])

        ## this is somewhat crude: ipptopsps programs are called like this: 
        ## ippjython foo.py [chunk] [other options]
        ## the logging code (called below by getLogger) wants to include 'name' in the 
        ## output file.  we blindly set name == argv[1] 
        ## programs which are called without argv[1] will use 'none' in the log file
        self.name = None
        if len(sys.argv) >= 2:
            self.name = sys.argv[1]

        # XXX this probably goes in 'config.py'
        self.configDir = os.getenv("IPPTOPSPS_DATA")
        if self.configDir is None:
            self.configDir = "../config/"
        else:
            self.configDir = self.configDir + "/"

        # self.configdir is set in ipptopsps.jy on init based on env(IPPTOPSPS_DATA)
        # for test purposes, an uninstalled system may use the config information from 
        # a relative path
        self.settingsPath = self.configDir + "settings.xml"

        self.logger = None

        self.settingsDoc = ElementTree(file=self.settingsPath)
        self.logPath = self.settingsDoc.find("logPath").text
        self.czarPlotsPath = self.settingsDoc.find("czarPlotsPath").text

        # print "config.programName: ", self.programName
        # print "config.configDir: ", self.configDir
        # print "config.settingsPath: ", self.settingsPath
        # print "config.logPath: ", self.logPath
        # print "config.test: ", self.test
        # print "config.czarPlotsPath: ", self.czarPlotsPath

        root = self.settingsDoc.getroot()
        localdb = root.find('localdatabase')
        for loaderhost in localdb.findall('loaderhost'):
          name = loaderhost.get('name')
          dbname = loaderhost.find('dbname').text
          dbhost = loaderhost.find('host').text
          print "loaderhost / dbhost : ", name, dbname, dbhost


    '''
    Creates a logger object and returns it
    '''
    def getLogger(self, host, pid, stdout=1, sendToFile=0):
        
        logging.setLoggerClass(PSLogger)
        self.logger = logging.getLogger(self.programName)
        if (self.name is None):
            self.logger.setup(self.programName, self.logPath, "none", host, pid, stdout, sendToFile)
        else:
            self.logger.setup(self.programName, self.logPath, self.name, host, pid, stdout, sendToFile)

        return self.logger

    '''
    Various db metadata getters
    '''
    def getDbName(self, dbType): 
        if dbType == 'localdatabase' or dbType == 'localdatabase_test':
            return self.scratchDbLeaf.find('name').text
        else:
            return self.settingsDoc.find(dbType +"/name").text

    def getDbHost(self, dbType): 
        if dbType == 'localdatabase' or dbType == 'localdatabase_test':
            return self.scratchDbLeaf.find('host').text
        else:
            return self.settingsDoc.find(dbType +"/host").text

    def getDbUser(self, dbType): 
        if dbType == 'localdatabase' or dbType == 'localdatabase_test':
            return self.scratchDbLeaf.find('user').text
        else:
            return self.settingsDoc.find(dbType +"/user").text

    def getDbPassword(self, dbType): 
        if dbType == 'localdatabase' or dbType == 'localdatabase_test':
            return self.scratchDbLeaf.find('password').text
        else:
            return self.settingsDoc.find(dbType +"/password").text

    def getDbMemory(self, dbType): 
        if dbType == 'localdatabase' or dbType == 'localdatabase_test':
            return self.scratchDbLeaf.find('memory').text
        else:
            print "memory is not a valid option for non-scratch databases..."
            raise

    def setScratchDbLeaf(self, myhost):
        root = self.settingsDoc.getroot()
        if (self.test):
            localdb = root.find('localdatabase_test')
        else:
            localdb = root.find('localdatabase')

        for loaderhost in localdb.findall('loader'):
          name = loaderhost.get('mach')
          # print "name, myhost: ", name, myhost
          if name == myhost:
              self.scratchDbLeaf = loaderhost
              return 1

        for loaderhost in localdb.findall('loader'):
          name = loaderhost.get('mach')
          # print "name, myhost: ", name, myhost
          if name == 'generic':
              self.scratchDbLeaf = loaderhost
              return 1

        print "Config Error: cannot find valid scratch db matching ", myhost, "or generic"
        raise
