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, 'os.getcwd', 'os.getcwd', False, 'import os\n'), (50, 'os.getenv', 'os.getenv', False, 'import os\n'), (24, 'schema.Optional', 'Optional', False, 'from schema import Use, Schema, SchemaError, Optional\n'), (25, 'schema.Optional', 'Optional', False, 'from schema import Use, Schema, SchemaError, Optional\n'), (20, 'schema.Use', 'Use', False, 'from schema import Use, Schema, SchemaError, Optional\n'), (21, 'schema.Use', 'Use', False, 'from schema import Use, Schema, SchemaError, Optional\n'), (22, 'schema.Use', 'Use', False, 'from schema import Use, Schema, SchemaError, Optional\n'), (52, 'os.path.exists', 'os.path.exists', False, 'import os\n'), (55, 'os.getcwd', 'os.getcwd', False, 'import os\n'), (90, 'yaml.dump', 'yaml.dump', False, 'import yaml\n'), (23, 'schema.Use', 'Use', False, 'from schema import Use, Schema, SchemaError, Optional\n'), (42, 'os.path.join', 'os.path.join', False, 'import os\n'), (88, 'logging.getLogger', 'logging.getLogger', False, 'import logging\n'), (37, 'os.path.join', 'os.path.join', False, 'import os\n'), (71, 'os.path.join', 'os.path.join', False, 'import os\n'), (34, 'os.path.join', 'os.path.join', False, 'import os\n'), (62, 'yaml.safe_load', 'yaml.safe_load', False, 'import yaml\n'), (59, 'os.path.join', 'os.path.join', False, 'import os\n')]