import inspect
from pathlib import Path


def _get_correct_module_str_for_callable(callable_obj):
    """

    When a script is called with `python path/to/script.py` the module path is
    wrong. This functions determines the module path as when the
    script was called with `python -m path.to.script`

    >>> _get_correct_module_str_for_callable(_get_correct_module_str_for_callable)
    'padertorch.configurable'
    >>> import torch.nn
    >>> _get_correct_module_str_for_callable(torch.nn.modules.linear.Linear)
    'torch.nn.modules.linear'

    >>> def foo(): pass
    >>> class Foo: pass

    >>> _get_correct_module_str_for_callable(foo)
    'padertorch.configurable'
    >>> _get_correct_module_str_for_callable(Foo)
    'padertorch.configurable'

    """

    if inspect.isclass(callable_obj):
        # classes have no __globals__
        file = inspect.getabsfile(callable_obj)
    elif inspect.isfunction(callable_obj):
        # inspect.getabsfile yields `/path/to/func<doctest func>`
        file = callable_obj.__globals__['__file__']
    else:
        raise TypeError(callable_obj)

    try:
        candidates = [
            f for f in Path(file).parents
            if (f / '__init__.py').exists()
        ]
        p = candidates[-1]

    except IndexError:
        raise Exception(file)
    module = '.'.join(
        Path(file).relative_to(p.parent).with_suffix('').parts)
    return module