# epydoc -- Logging
#
# Copyright (C) 2005 Edward Loper
# Author: Edward Loper <edloper@loper.org>
# URL: <http://epydoc.sf.net>
#
# $Id: log.py 1488 2007-02-14 00:34:27Z edloper $

"""
Functions used to report messages and progress updates to the user.
These functions are delegated to zero or more registered L{Logger}
objects, which are responsible for actually presenting the information
to the user.  Different interfaces are free to create and register
their own C{Logger}s, allowing them to present this information in the
manner that is best suited to each interface.

@note: I considered using the standard C{logging} package to provide
this functionality.  However, I found that it would be too difficult
to get that package to provide the behavior I want (esp. with respect
to progress displays; but also with respect to message blocks).

@group Message Severity Levels: DEBUG, INFO, WARNING, ERROR, FATAL
"""
__docformat__ = 'epytext en'

import sys, os

DEBUG = 10
INFO = 20
DOCSTRING_WARNING = 25
WARNING = 30
ERROR = 40
FATAL = 40

######################################################################
# Logger Base Class
######################################################################
class Logger:
    """
    An abstract base class that defines the interface for X{loggers},
    which are used by epydoc to report information back to the user.
    Loggers are responsible for tracking two types of information:
    
        - Messages, such as warnings and errors.
        - Progress on the current task.

    This abstract class allows the command-line interface and the
    graphical interface to each present this information to the user
    in the way that's most natural for each interface.  To set up a
    logger, create a subclass of C{Logger} that overrides all methods,
    and register it using L{register_logger}.
    """
    #////////////////////////////////////////////////////////////
    # Messages
    #////////////////////////////////////////////////////////////

    def log(self, level, message):
        """
        Display a message.

        @param message: The message string to display.  C{message} may
        contain newlines, but does not need to end in a newline.
        @param level: An integer value indicating the severity of the
        message.
        """

    def close(self):
        """
        Perform any tasks needed to close this logger.
        """

    #////////////////////////////////////////////////////////////
    # Message blocks
    #////////////////////////////////////////////////////////////
    
    def start_block(self, header):
        """
        Start a new message block.  Any calls to L{info()},
        L{warning()}, or L{error()} that occur between a call to
        C{start_block} and a corresponding call to C{end_block} will
        be grouped together, and displayed with a common header.
        C{start_block} can be called multiple times (to form nested
        blocks), but every call to C{start_block} I{must} be balanced
        by a call to C{end_block}.
        """
        
    def end_block(self):
        """
        End a warning block.  See L{start_block} for details.
        """

    #////////////////////////////////////////////////////////////
    # Progress bar
    #////////////////////////////////////////////////////////////
    
    def start_progress(self, header=None):
        """
        Begin displaying progress for a new task.  C{header} is a
        description of the task for which progress is being reported.
        Each call to C{start_progress} must be followed by a call to
        C{end_progress} (with no intervening calls to
        C{start_progress}).
        """

    def end_progress(self):
        """
        Finish off the display of progress for the current task.  See
        L{start_progress} for more information.
        """

    def progress(self, percent, message=''):
        """
        Update the progress display.
        
        @param percent: A float from 0.0 to 1.0, indicating how much
            progress has been made.
        @param message: A message indicating the most recent action
            that contributed towards that progress.
        """

class SimpleLogger(Logger):
    def __init__(self, threshold=WARNING):
        self.threshold = threshold
    def log(self, level, message):
        if level >= self.threshold: print message
        
######################################################################
# Logger Registry
######################################################################

_loggers = []
"""
The list of registered logging functions.
"""

def register_logger(logger):
    """
    Register a logger.  Each call to one of the logging functions
    defined by this module will be delegated to each registered
    logger.
    """
    _loggers.append(logger)

def remove_logger(logger):
    _loggers.remove(logger)

######################################################################
# Logging Functions
######################################################################
# The following methods all just delegate to the corresponding 
# methods in the Logger class (above) for each registered logger.

def fatal(*messages):
    """Display the given fatal message."""
    message = ' '.join(['%s' % (m,) for m in messages])
    for logger in _loggers: logger.log(FATAL, message)
    
def error(*messages):
    """Display the given error message."""
    message = ' '.join(['%s' % (m,) for m in messages])
    for logger in _loggers: logger.log(ERROR, message)
    
def warning(*messages):
    """Display the given warning message."""
    message = ' '.join(['%s' % (m,) for m in messages])
    for logger in _loggers: logger.log(WARNING, message)
    
def docstring_warning(*messages):
    """Display the given docstring warning message."""
    message = ' '.join(['%s' % (m,) for m in messages])
    for logger in _loggers: logger.log(DOCSTRING_WARNING, message)
    
def info(*messages):
    """Display the given informational message."""
    message = ' '.join(['%s' % (m,) for m in messages])
    for logger in _loggers: logger.log(INFO, message)
    
def debug(*messages):
    """Display the given debugging message."""
    message = ' '.join(['%s' % (m,) for m in messages])
    for logger in _loggers: logger.log(DEBUG, message)
    
def start_block(header):
    for logger in _loggers: logger.start_block(header)
start_block.__doc__ = Logger.start_block.__doc__
    
def end_block():
    for logger in _loggers: logger.end_block()
end_block.__doc__ = Logger.end_block.__doc__
    
def start_progress(header=None):
    for logger in _loggers: logger.start_progress(header)
start_progress.__doc__ = Logger.start_progress.__doc__
    
def end_progress():
    for logger in _loggers: logger.end_progress()
end_progress.__doc__ = Logger.end_progress.__doc__
    
def progress(percent, message=''):
    for logger in _loggers: logger.progress(percent, '%s' % message)
progress.__doc__ = Logger.progress.__doc__

def close():
    for logger in _loggers: logger.close()
