"""Utility functions for finding modules

Utility functions for finding modules on sys.path.

"""
from __future__ import annotations

#-----------------------------------------------------------------------------
# Copyright (c) 2011, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Stdlib imports
import importlib
import importlib.abc
import importlib.util
import sys

# Third-party imports

# Our own imports


#-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Local utilities
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------

def find_mod(module_name: str) -> str | None | importlib.abc.Loader:
    """
    Find module `module_name` on sys.path, and return the path to module `module_name`.

    * If `module_name` refers to a module directory, then return path to `__init__` file.
        * If `module_name` is a directory without an __init__file, return None.

    * If module is missing or does not have a `.py` or `.pyw` extension, return None.
        * Note that we are not interested in running bytecode.

    * Otherwise, return the fill path of the module.

    Parameters
    ----------
    module_name : str

    Returns
    -------
    module_path : str
        Path to module `module_name`, its __init__.py, or None,
        depending on above conditions.
    """
    spec = importlib.util.find_spec(module_name)
    if spec is None:
        return None
    module_path = spec.origin
    if module_path is None:
        # built-in/frozen modules use their own meta_path finder as loader
        if spec.loader is not None and spec.loader in sys.meta_path:  # type: ignore[comparison-overlap]
            return spec.loader  # type: ignore[unreachable]
        return None
    else:
        split_path = module_path.split(".")
        if split_path[-1] in ["py", "pyw"]:
            return module_path
        else:
            return None
