"""A singleton class for accessing global config values

provides access to global configuration file
"""

__author__ = 'raphtee@google.com (Travis Miller)'

import os, sys, ConfigParser, logging
from autotest_lib.client.common_lib import error


class ConfigError(error.AutotestError):
    pass


class ConfigValueError(ConfigError):
    pass



common_lib_dir = os.path.dirname(sys.modules[__name__].__file__)
client_dir = os.path.dirname(common_lib_dir)
root_dir = os.path.dirname(client_dir)

# Check if the config files are at autotest's root dir
# This will happen if client is executing inside a full autotest tree, or if
# other entry points are being executed
global_config_path_root = os.path.join(root_dir, 'global_config.ini')
shadow_config_path_root = os.path.join(root_dir, 'shadow_config.ini')
config_in_root = os.path.exists(global_config_path_root)

# Check if the config files are at autotest's client dir
# This will happen if a client stand alone execution is happening
global_config_path_client = os.path.join(client_dir, 'global_config.ini')
config_in_client = os.path.exists(global_config_path_client)

if config_in_root:
    DEFAULT_CONFIG_FILE = global_config_path_root
    if os.path.exists(shadow_config_path_root):
        DEFAULT_SHADOW_FILE = shadow_config_path_root
    else:
        DEFAULT_SHADOW_FILE = None
    RUNNING_STAND_ALONE_CLIENT = False
elif config_in_client:
    DEFAULT_CONFIG_FILE = global_config_path_client
    DEFAULT_SHADOW_FILE = None
    RUNNING_STAND_ALONE_CLIENT = True
else:
    DEFAULT_CONFIG_FILE = None
    DEFAULT_SHADOW_FILE = None
    RUNNING_STAND_ALONE_CLIENT = True

class global_config(object):
    _NO_DEFAULT_SPECIFIED = object()

    config = None
    config_file = DEFAULT_CONFIG_FILE
    shadow_file = DEFAULT_SHADOW_FILE
    running_stand_alone_client = RUNNING_STAND_ALONE_CLIENT


    def check_stand_alone_client_run(self):
        return self.running_stand_alone_client


    def set_config_files(self, config_file=DEFAULT_CONFIG_FILE,
                            shadow_file=DEFAULT_SHADOW_FILE):
        self.config_file = config_file
        self.shadow_file = shadow_file
        self.config = None


    def _handle_no_value(self, section, key, default):
        if default is self._NO_DEFAULT_SPECIFIED:
            msg = ("Value '%s' not found in section '%s'" %
                   (key, section))
            raise ConfigError(msg)
        else:
            return default


    def get_section_values(self, section):
        """
        Return a config parser object containing a single section of the
        global configuration, that can be later written to a file object.

        @param section: Section we want to turn into a config parser object.
        @return: ConfigParser() object containing all the contents of section.
        """
        cfgparser = ConfigParser.ConfigParser()
        cfgparser.add_section(section)
        for option, value in self.config.items(section):
            cfgparser.set(section, option, value)
        return cfgparser


    def get_config_value(self, section, key, type=str,
                         default=_NO_DEFAULT_SPECIFIED, allow_blank=False):
        """Get a configuration value

        @param section: Section the key is in.
        @param key: The key to look up.
        @param type: The expected type of the returned value.
        @param default: A value to return in case the key couldn't be found.
        @param allow_blank: If False, an empty string as a value is treated like
                            there was no value at all. If True, empty strings
                            will be returned like they were normal values.

        @raises ConfigError: If the key could not be found and no default was
                             specified.

        @return: The obtained value or default.
        """
        self._ensure_config_parsed()

        try:
            val = self.config.get(section, key)
        except ConfigParser.Error:
            return self._handle_no_value(section, key, default)

        if not val.strip() and not allow_blank:
            return self._handle_no_value(section, key, default)

        return self._convert_value(key, section, val, type)


    # This order of parameters ensures this can be called similar to the normal
    # get_config_value which is mostly called with (section, key, type).
    def get_config_value_with_fallback(self, section, key, fallback_key,
                                       type=str, fallback_section=None,
                                       default=_NO_DEFAULT_SPECIFIED, **kwargs):
        """Get a configuration value if it exists, otherwise use fallback.

        Tries to obtain a configuration value for a given key. If this value
        does not exist, the value looked up under a different key will be
        returned.

        @param section: Section the key is in.
        @param key: The key to look up.
        @param fallback_key: The key to use in case the original key wasn't
                             found.
        @param type: data type the value should have.
        @param fallback_section: The section the fallback key resides in. In
                                 case none is specified, the the same section as
                                 for the primary key is used.
        @param default: Value to return if values could neither be obtained for
                        the key nor the fallback key.
        @param **kwargs: Additional arguments that should be passed to
                         get_config_value.

        @raises ConfigError: If the fallback key doesn't exist and no default
                             was provided.

        @return: The value that was looked up for the key. If that didn't
                 exist, the value looked up for the fallback key will be
                 returned. If that also didn't exist, default will be returned.
        """
        if fallback_section is None:
            fallback_section = section

        try:
            return self.get_config_value(section, key, type, **kwargs)
        except ConfigError:
            return self.get_config_value(fallback_section, fallback_key,
                                         type, default=default, **kwargs)


    def override_config_value(self, section, key, new_value):
        """
        Override a value from the config file with a new value.
        """
        self._ensure_config_parsed()
        self.config.set(section, key, new_value)


    def reset_config_values(self):
        """
        Reset all values to those found in the config files (undoes all
        overrides).
        """
        self.parse_config_file()


    def _ensure_config_parsed(self):
        if self.config is None:
            self.parse_config_file()


    def merge_configs(self, shadow_config):
        # overwrite whats in config with whats in shadow_config
        sections = shadow_config.sections()
        for section in sections:
            # add the section if need be
            if not self.config.has_section(section):
                self.config.add_section(section)
            # now run through all options and set them
            options = shadow_config.options(section)
            for option in options:
                val = shadow_config.get(section, option)
                self.config.set(section, option, val)


    def parse_config_file(self):
        self.config = ConfigParser.ConfigParser()
        if self.config_file and os.path.exists(self.config_file):
            self.config.read(self.config_file)
        else:
            raise ConfigError('%s not found' % (self.config_file))

        # now also read the shadow file if there is one
        # this will overwrite anything that is found in the
        # other config
        if self.shadow_file and os.path.exists(self.shadow_file):
            shadow_config = ConfigParser.ConfigParser()
            shadow_config.read(self.shadow_file)
            # now we merge shadow into global
            self.merge_configs(shadow_config)


    # the values that are pulled from ini
    # are strings.  But we should attempt to
    # convert them to other types if needed.
    def _convert_value(self, key, section, value, value_type):
        # strip off leading and trailing white space
        sval = value.strip()

        # if length of string is zero then return None
        if len(sval) == 0:
            if value_type == str:
                return ""
            elif value_type == bool:
                return False
            elif value_type == int:
                return 0
            elif value_type == float:
                return 0.0
            elif value_type == list:
                return []
            else:
                return None

        if value_type == bool:
            if sval.lower() == "false":
                return False
            else:
                return True

        if value_type == list:
            # Split the string using ',' and return a list
            return [val.strip() for val in sval.split(',')]

        try:
            conv_val = value_type(sval)
            return conv_val
        except:
            msg = ("Could not convert %s value %r in section %s to type %s" %
                    (key, sval, section, value_type))
            raise ConfigValueError(msg)


    def get_sections(self):
        """Return a list of sections available."""
        self._ensure_config_parsed()
        return self.config.sections()


# insure the class is a singleton.  Now the symbol global_config
# will point to the one and only one instace of the class
global_config = global_config()
