import os
import logging
import yaml
from schema import Use, Schema, SchemaError, Optional


class InvalidConfig(Exception):
    pass


class MissingConfig(Exception):
    pass


default_config = {
    'logging': 30,
    'migrate_from_0_3_2': True
}
schema = Schema({
    'stellar_url': Use(str),
    'url': Use(str),
    'project_name': Use(str),
    'tracked_databases': [Use(str)],
    Optional('logging'): int,
    Optional('migrate_from_0_3_2'): bool
})


def get_config_path():
    current_directory = os.getcwd()
    while True:
        try:
            with open(
                os.path.join(current_directory, 'stellar.yaml'),
                'rb'
            ) as fp:
                return os.path.join(current_directory, 'stellar.yaml')
        except IOError:
            pass

        current_directory = os.path.abspath(
            os.path.join(current_directory, '..')
        )
        if current_directory == '/':
            return None


def load_config():
    config = {}
    stellar_config_env = os.getenv('STELLAR_CONFIG')
    if stellar_config_env:
        if os.path.exists(stellar_config_env):
            config = yaml.safe_load(open(stellar_config_env))
    else:
        current_directory = os.getcwd()
        while True:
            try:
                with open(
                    os.path.join(current_directory, 'stellar.yaml'),
                    'rb'
                ) as fp:
                    config = yaml.safe_load(fp)
                    break
            except IOError:
                pass

            if current_directory == '/':
                break

            current_directory = os.path.abspath(
                os.path.join(current_directory, '..')
            )

    if not config:
        raise MissingConfig()

    for k, v in default_config.items():
        if k not in config:
            config[k] = v

    try:
        return schema.validate(config)
    except SchemaError as e:
        raise InvalidConfig(e)


def save_config(config):
    logging.getLogger(__name__).debug('save_config()')
    with open(get_config_path(), "w") as fp:
        yaml.dump(config, fp)

[((30, 24, 30, 35), 'os.getcwd', 'os.getcwd', ({}, {}), '()', False, 'import os\n'), ((50, 25, 50, 52), 'os.getenv', 'os.getenv', ({(50, 35, 50, 51): '"""STELLAR_CONFIG"""'}, {}), "('STELLAR_CONFIG')", False, 'import os\n'), ((24, 4, 24, 23), 'schema.Optional', 'Optional', ({(24, 13, 24, 22): '"""logging"""'}, {}), "('logging')", False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((25, 4, 25, 34), 'schema.Optional', 'Optional', ({(25, 13, 25, 33): '"""migrate_from_0_3_2"""'}, {}), "('migrate_from_0_3_2')", False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((20, 19, 20, 27), 'schema.Use', 'Use', ({(20, 23, 20, 26): 'str'}, {}), '(str)', False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((21, 11, 21, 19), 'schema.Use', 'Use', ({(21, 15, 21, 18): 'str'}, {}), '(str)', False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((22, 20, 22, 28), 'schema.Use', 'Use', ({(22, 24, 22, 27): 'str'}, {}), '(str)', False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((52, 11, 52, 45), 'os.path.exists', 'os.path.exists', ({(52, 26, 52, 44): 'stellar_config_env'}, {}), '(stellar_config_env)', False, 'import os\n'), ((55, 28, 55, 39), 'os.getcwd', 'os.getcwd', ({}, {}), '()', False, 'import os\n'), ((90, 8, 90, 29), 'yaml.dump', 'yaml.dump', ({(90, 18, 90, 24): 'config', (90, 26, 90, 28): 'fp'}, {}), '(config, fp)', False, 'import yaml\n'), ((23, 26, 23, 34), 'schema.Use', 'Use', ({(23, 30, 23, 33): 'str'}, {}), '(str)', False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((42, 12, 42, 49), 'os.path.join', 'os.path.join', ({(42, 25, 42, 42): 'current_directory', (42, 44, 42, 48): '""".."""'}, {}), "(current_directory, '..')", False, 'import os\n'), ((88, 4, 88, 31), 'logging.getLogger', 'logging.getLogger', ({(88, 22, 88, 30): '__name__'}, {}), '(__name__)', False, 'import logging\n'), ((37, 23, 37, 70), 'os.path.join', 'os.path.join', ({(37, 36, 37, 53): 'current_directory', (37, 55, 37, 69): '"""stellar.yaml"""'}, {}), "(current_directory, 'stellar.yaml')", False, 'import os\n'), ((71, 16, 71, 53), 'os.path.join', 'os.path.join', ({(71, 29, 71, 46): 'current_directory', (71, 48, 71, 52): '""".."""'}, {}), "(current_directory, '..')", False, 'import os\n'), ((34, 16, 34, 63), 'os.path.join', 'os.path.join', ({(34, 29, 34, 46): 'current_directory', (34, 48, 34, 62): '"""stellar.yaml"""'}, {}), "(current_directory, 'stellar.yaml')", False, 'import os\n'), ((62, 29, 62, 47), 'yaml.safe_load', 'yaml.safe_load', ({(62, 44, 62, 46): 'fp'}, {}), '(fp)', False, 'import yaml\n'), ((59, 20, 59, 67), 'os.path.join', 'os.path.join', ({(59, 33, 59, 50): 'current_directory', (59, 52, 59, 66): '"""stellar.yaml"""'}, {}), "(current_directory, 'stellar.yaml')", False, 'import os\n')]