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)

[((508, 519), 'os.getcwd', 'os.getcwd', ([], {}), '()\n', (517, 519), False, 'import os\n'), ((1020, 1047), 'os.getenv', 'os.getenv', (['"""STELLAR_CONFIG"""'], {}), "('STELLAR_CONFIG')\n", (1029, 1047), False, 'import os\n'), ((389, 408), 'schema.Optional', 'Optional', (['"""logging"""'], {}), "('logging')\n", (397, 408), False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((419, 449), 'schema.Optional', 'Optional', (['"""migrate_from_0_3_2"""'], {}), "('migrate_from_0_3_2')\n", (427, 449), False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((287, 295), 'schema.Use', 'Use', (['str'], {}), '(str)\n', (290, 295), False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((308, 316), 'schema.Use', 'Use', (['str'], {}), '(str)\n', (311, 316), False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((338, 346), 'schema.Use', 'Use', (['str'], {}), '(str)\n', (341, 346), False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((1086, 1120), 'os.path.exists', 'os.path.exists', (['stellar_config_env'], {}), '(stellar_config_env)\n', (1100, 1120), False, 'import os\n'), ((1222, 1233), 'os.getcwd', 'os.getcwd', ([], {}), '()\n', (1231, 1233), False, 'import os\n'), ((2111, 2132), 'yaml.dump', 'yaml.dump', (['config', 'fp'], {}), '(config, fp)\n', (2120, 2132), False, 'import yaml\n'), ((374, 382), 'schema.Use', 'Use', (['str'], {}), '(str)\n', (377, 382), False, 'from schema import Use, Schema, SchemaError, Optional\n'), ((849, 886), 'os.path.join', 'os.path.join', (['current_directory', '""".."""'], {}), "(current_directory, '..')\n", (861, 886), False, 'import os\n'), ((2007, 2034), 'logging.getLogger', 'logging.getLogger', (['__name__'], {}), '(__name__)\n', (2024, 2034), False, 'import logging\n'), ((702, 749), 'os.path.join', 'os.path.join', (['current_directory', '"""stellar.yaml"""'], {}), "(current_directory, 'stellar.yaml')\n", (714, 749), False, 'import os\n'), ((1670, 1707), 'os.path.join', 'os.path.join', (['current_directory', '""".."""'], {}), "(current_directory, '..')\n", (1682, 1707), False, 'import os\n'), ((588, 635), 'os.path.join', 'os.path.join', (['current_directory', '"""stellar.yaml"""'], {}), "(current_directory, 'stellar.yaml')\n", (600, 635), False, 'import os\n'), ((1446, 1464), 'yaml.safe_load', 'yaml.safe_load', (['fp'], {}), '(fp)\n', (1460, 1464), False, 'import yaml\n'), ((1318, 1365), 'os.path.join', 'os.path.join', (['current_directory', '"""stellar.yaml"""'], {}), "(current_directory, 'stellar.yaml')\n", (1330, 1365), False, 'import os\n')]