import itertools
import logging

logger = logging.getLogger(__name__)


def skip_to(end_skip):
    """Skip lines until a line is found that starts with end_skip."""

    def _skip_to(fobj):
        logger.debug(f"skipping lines until line starts with {end_skip!r}")
        for line in fobj:
            if isinstance(line, bytes):
                line = line.decode()
            if line.startswith(end_skip):
                logger.debug(f"found line starting with {end_skip!r}: {line!r}")
                return

    return _skip_to


def iter_wo_comments(fobj, indicator="#", skips: dict[str, callable] = None):
    """Remove comments.

    This is a crude method to remove comments, that is unaware of strings, escape
    characters or anything else.

    Args:
        fobj (file object): file
        indicator (str, default '#'): indicator for the start of a comment

    Yields:
        str
    """
    if skips is None:
        skips = {}

    for line in fobj:
        if isinstance(line, bytes):
            line = line.decode()

        if line in skips:
            skips[line](fobj)
            continue

        remaining = line.split(indicator)[0].strip()
        if remaining:
            yield remaining
        else:
            pass
            # logger.debug("skipped comment or empty line: %r", line)


def coord_minmax(nodes):
    """Calculate the maximal and minimal coordinate value for each direction.

    If the list is empty return zeros.

    Args:
        nodes (Iterable): list of nodes

    Returns:
        tuple
    """
    if not nodes:
        return [0, 0, 0], [0, 0, 0]
    cmin = [float("inf")] * 3
    cmax = [float("-inf")] * 3
    for node in nodes:
        for i in range(3):
            cmin[i] = min((node.in_3d[i], cmin[i]))
            cmax[i] = max((node.in_3d[i], cmax[i]))
    return cmin, cmax


def peek(generator):
    """
    Take a peek at the first element of a generator without consuming it.
    If the generator is empty, return None and an empty generator.
    """
    try:
        first = next(generator)
    except StopIteration:
        return None, generator
    return first, itertools.chain([first], generator)
