# Karl O. Pinc <kop@karlpinc.com>

'''Library supporting YAML config files
'''

import logging
import sys
import yaml


class ConflibError(Exception):
    pass


class NoSuchKeyError(ConflibError):
    pass


def _yaml_fd_to_dict(logger, fd, path):
    try:
        return yaml.safe_load(fd)
    except yaml.YAMLError as ex:
        logger.critical(
            f'{sys.argv[0]}: Cannot parse config file ({path}) '
            f'as a YAML document: {ex}')
        sys.exit(1)


def dict_from_path(logger, path, expected=True):
    try:
        fd = open(path)
    except OSError as ex:
        if expected:
            logger.critical(
                f'{sys.argv[0]}: Cannot open config file ({path}): {ex}')
            sys.exit(1)
        else:
            logger.debug(
                f'{sys.argv[0]}: No config file available at ({path}): {ex}')
            return None

    with fd:
        return _yaml_fd_to_dict(logger, fd, path)


def getcfg(conf, key):
    '''Thin wrapper around conf[key] to raise an exception when
    the expected key does not exist
    '''
    try:
        return conf[key]
    except KeyError:
        raise NoSuchKeyError(
            f'The key ({key}) is not found '
            'in the portion of the configuration being examined')


#
# Logging
#

def load_logging_config(logger, conf, path):
    if conf is not None:
        if 'logger' in conf:
            logconf = conf['logger']
            try:
                logging.config.dictConfig(logconf)
            except (ValueError, TypeError, AttributeError, ImportError) as ex:
                logger.critical(f'{sys.argv[0]}: Config file ({path}) is not '
                                f'acceptable to the logging module: {ex}')
                sys.exit(1)
        else:
            logger.critical(
                f'{sys.argv[0]}: Config file ({path}) has no top-level '
                '"logger" node')
            sys.exit(1)
