"""This module allows client-specific code to be imported across the MTP codebase."""

from importlib import import_module
import logging

from django.conf import settings


logger = logging.getLogger('mtp.generic')  # pylint: disable=C0103


def mtp_import(generic_module_path, force_generic=False, force_specific=False):
    """Allows a module to be imported from a client-specific path if possible.

    Parameters
    ----------
    generic_module_path : str
        The path of the MTP module to load, starting at ``mtp``.
        For example: 'mtp.apps.trainings.models'.
    force_generic : bool
        If ``True``, the generic version of the module will be used.
    force_specific : bool
        If ``True``, the specific version of the module will be used.
        An ``ImportError`` will be raised if such module cannot actually
        be found and imported successfully.

    Returns
    -------
    module
        The imported Python module.

    Raises
    ------
    ImportError
        If no module could be imported.
    RuntimeError
        If both ``force_generic`` and ``force_specific`` are ``True``.

    Notes
    -----
    This function relies on the ``MTP_INSTANCE_NAME`` environment setting,
    imported in ``settings/base.py`` under the ``INSTANCE_NAME`` variable name.

    Right now the custom code path is hardcoded, but a future version might
    make it configurable, or take advantage of Python packaging to supply
    client specific code as external dependencies. This is good enough for now.

    See also
    --------
    This module's ``tests.py`` file, for usage examples.

    """

    # A little sanity check.
    if force_generic and force_specific:
        raise RuntimeError(
            "The `force_generic` and `force_specific` options are mutually exclusive."
        )

    # Unless we required the generic version we should first try to import
    # a specific version of the module.
    if not force_generic:

        # Yes! But which one? Let's find out.

        # The specific version of a module under 'mtp.apps' is
        # available under 'mtp.custom.[instance_name].apps'...
        specific_module_path = generic_module_path.replace(
            'mtp.apps', 'mtp.custom.%s.apps' % settings.INSTANCE_NAME
        )

        try:


            # ... so we try to import it from there...
            module = import_module(specific_module_path)
            logger.debug(
                "Successfully imported specific module '%s'", specific_module_path
            )

            # ... and return it if it worked.
            return module

        except ImportError:

            # But it may not have actually worked :()
            logger.debug(
                "Failed to import specific module '%s'", specific_module_path
            )

            # Did we absolutely want the specific version?
            if force_specific:

                # Yep. Raise.
                logger.debug("`force_specific` is `True` => bubbling up exception")
                raise

            else:

                # Nope. Let's carry on and try the generic one.
                logger.debug("`force_specific` is `False` => trying generic module")

    else:

        # Forget about the specific version, we want the original thing.
        logger.debug("`force_generic` is `True` => skipping specific import attempt")

    # OK, let's go with the generic version then. Hopefully it exists.
    return import_module(generic_module_path)
