import logging
import sys


VERBOSITY = 3


# The root logger for the whole top-level package:
_logger = logging.getLogger(__name__.rpartition('.')[0])


def configure_logger(logger, verbosity=VERBOSITY, *,
                     logfile=None,
                     maxlevel=logging.CRITICAL,
                     ):
    level = max(1,  # 0 disables it, so we use the next lowest.
                min(maxlevel,
                    maxlevel - verbosity * 10))
    logger.setLevel(level)
    #logger.propagate = False

    if not logger.handlers:
        if logfile:
            handler = logging.FileHandler(logfile)
        else:
            handler = logging.StreamHandler(sys.stdout)
        handler.setLevel(level)
        #handler.setFormatter(logging.Formatter())
        logger.addHandler(handler)

    # In case the provided logger is in a sub-package...
    if logger is not _logger:
        configure_logger(
            _logger,
            verbosity,
            logfile=logfile,
            maxlevel=maxlevel,
        )


def hide_emit_errors():
    """Ignore errors while emitting log entries.

    Rather than printing a message describing the error, we show nothing.
    """
    # For now we simply ignore all exceptions.  If we wanted to ignore
    # specific ones (e.g. BrokenPipeError) then we would need to use
    # a Handler subclass with a custom handleError() method.
    orig = logging.raiseExceptions
    logging.raiseExceptions = False
    def restore():
        logging.raiseExceptions = orig
    return restore


class Printer:
    def __init__(self, verbosity=VERBOSITY):
        self.verbosity = verbosity

    def info(self, *args, **kwargs):
        if self.verbosity < 3:
            return
        print(*args, **kwargs)
