"""
This module takes care of finding information about the runtime of Lexicon:
* what are the providers installed, and available
* what is the version of Lexicon
"""
import pkgutil

import pkg_resources

from lexicon import providers


def find_providers():
    """Find all providers registered in Lexicon, and their availability"""
    providers_list = sorted({modname for (_, modname, _)
                             in pkgutil.iter_modules(providers.__path__)
                             if modname != 'base'})

    try:
        distribution = pkg_resources.get_distribution('dns-lexicon')
    except pkg_resources.DistributionNotFound:
        return {provider: True for provider in providers_list}
    else:
        return {provider: _resolve_requirements(provider, distribution)
                for provider in providers_list}


def lexicon_version():
    """Retrieve current Lexicon version"""
    try:
        return pkg_resources.get_distribution('dns-lexicon').version
    except pkg_resources.DistributionNotFound:
        return 'unknown'


def _resolve_requirements(provider, distribution):
    try:
        requirements = distribution.requires([provider])
    except pkg_resources.UnknownExtra:
        # No extra for this provider
        return True
    else:
        # Extra is defined
        try:
            for requirement in requirements:
                if hasattr(requirement, 'name'):
                    pkg_resources.get_distribution(requirement.name)
                else:
                    pkg_resources.get_distribution(requirement)
        except (pkg_resources.DistributionNotFound, pkg_resources.VersionConflict):
            # At least one extra requirement is not fulfilled
            return False

    return True
