# This file is part of the Coral project.
# Please read the copyright notice in the LICENSE file.

import logging
import logging.handlers
import sys
import os

#
# When multiple sessions log to the same file over NFS,
# we get stale NFS file handles. This raises a ValueError
# in
#File "/usr/src/build/394694-i386/install/usr/lib/python2.3/logging/__init__.py
#", line 879, in debug
#File "/usr/src/build/394694-i386/install/usr/lib/python2.3/logging/__init__.py
#", line 994, in _log
#File "/usr/src/build/394694-i386/install/usr/lib/python2.3/logging/__init__.py
#", line 1004, in handle
#File "/usr/src/build/394694-i386/install/usr/lib/python2.3/logging/__init__.py
#", line 1037, in callHandlers
#File "/usr/src/build/394694-i386/install/usr/lib/python2.3/logging/__init__.py
#", line 592, in handle
#File "/usr/src/build/394694-i386/install/usr/lib/python2.3/logging/handlers.py
#", line 103, in emit
#ValueError: I/O operation on closed file
#
# And thus, we're overriding logging.Logger._log
#

_old_logger = logging.Logger._log
def __log_overrider(self, *args, **kwargs):
    try:
        _old_logger(self, *args, **kwargs)
    except:
        pass

logging.Logger._log = __log_overrider

#
#Traceback (most recent call last):
#File "/usr/src/build/394694-i386/install/usr/lib/python2.3/logging/__init__.py
#", line 682, in emit
#  File "/usr/src/build/394694-i386/install/usr/lib/python2.3/logging/__init__.py
#", line 661, in flush
#IOError: [Errno 116] Stale NFS file handle
#
#
old_flush = logging.StreamHandler.flush
def __flush_overrider(self, *args, **kwargs):
    try:
        old_flush(self, *args, **kwargs)
    except:
        pass
logging.StreamHandler.flush = __flush_overrider
#
# Using this is not enough, clients get killed by
# a mysterious "fatal IO error: client killed" message
#
### logging.raiseExceptions = 0




# um, I can't query for the level names?
__levels = ( ("all", 0),
             ("debug", 10),
             ("info", 20),
             ("warning", 30),
             ("warn", 30),
             ("error", 40),
             ("fatal", 50),
             ("critical", 50),
             ("none", 999),     # arbitrary sentinel
             )

__currentLogLevel = 0

def getCurrentLogLevel():
    global __currentLogLevel
    return __currentLogLevel

def __setDebugLevel(logger):
    global __currentLogLevel
    s = os.getenv("CORALDEBUG")
    if not s:
        return
    global __levels
    for (level, value) in __levels:
        if level == s:
            logger.setLevel(value)
            __currentLogLevel = value
            return

def getLogger(name="Coral"):
    global logger
    global __setDebugLevel
    global __currentLogLevel

    if logger:
        return logger
    
    try:
        os.mkdir(os.path.expanduser('~/.coral/'))
    except:
        pass

    #td = tempfile.mkdtemp("coral", os.path.expandvars("${USER}"))
    #if td:
    #    dfile = os.path.expandvars(td+"/${USER}_coral_debug.txt")
    #else:
    #    dfile = os.path.expandvars("/tmp/${USER}_coral_debug.txt")

    # create the file in the home folder
    dfile= os.path.expanduser('~/.coral/coral_debug.txt')
                                    
    logger = logging.getLogger(name)
    logger.setLevel(logging.WARNING)
    __currentLogLevel = 30
    __setDebugLevel(logger)
    hdlr = logging.StreamHandler(sys.stderr)
    
    try:
        # limit debug file to 64KB
        hdlr2 = logging.handlers.RotatingFileHandler(dfile,"a",2**16,1)
    except IOError:
        hdlr2 = logging.handlers.RotatingFileHandler("/dev/null")
    formatter = logging.Formatter('%(levelname)s %(message)s')
    hdlr.setFormatter(formatter)
    formatter2 = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
    hdlr2.setFormatter(formatter2)
    
    logger.addHandler(hdlr)
    logger.addHandler(hdlr2) 
    logger.info("Coral logger started")
                                           
    return  logger



#
# The global logger will by default log warnings
# However, this can be set with the CORALDEBUG environment
# variable. Legal values are Python's ordinary logging levels
# The C++ core also does its own similar logging
#
#
logger=None
logger=getLogger()

