# Copyright 2011 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

'''Utility functions and objects for logging.'''

import logging
import sys


class StdoutStderrHandler(logging.Handler):
  '''Subclass of logging.Handler which outputs to either stdout or stderr
  based on a threshold level.
  '''

  def __init__(self, threshold=logging.WARNING, err=sys.stderr, out=sys.stdout):
    '''Args:
    threshold: below this logging level messages are sent to stdout,
      otherwise they are sent to stderr
    err: a stream object that error messages are sent to, defaults to
      sys.stderr
    out: a stream object that non-error messages are sent to, defaults to
      sys.stdout
    '''
    logging.Handler.__init__(self)
    self._err = logging.StreamHandler(err)
    self._out = logging.StreamHandler(out)
    self._threshold = threshold
    self._last_was_err = False

  def setLevel(self, lvl):
    logging.Handler.setLevel(self, lvl)
    self._err.setLevel(lvl)
    self._out.setLevel(lvl)

  def setFormatter(self, formatter):
    logging.Handler.setFormatter(self, formatter)
    self._err.setFormatter(formatter)
    self._out.setFormatter(formatter)

  def emit(self, record):
    if record.levelno < self._threshold:
      self._out.emit(record)
      self._last_was_err = False
    else:
      self._err.emit(record)
      self._last_was_err = False

  def flush(self):
    # preserve order on the flushing, the stalest stream gets flushed first
    if self._last_was_err:
      self._out.flush()
      self._err.flush()
    else:
      self._err.flush()
      self._out.flush()


FORMAT = "%(asctime)s %(filename)s [%(levelname)s] %(message)s"
DATEFMT = "%H:%M:%S"


def config_root(
  level=logging.INFO, threshold=logging.WARNING, format=FORMAT, datefmt=DATEFMT
):
  '''Configure the root logger to use a StdoutStderrHandler and some default
  formatting.
    Args:
      level: messages below this level are ignored
      threshold: below this logging level messages are sent to stdout,
        otherwise they are sent to stderr
      format: format for log messages, see logger.Format
      datefmt: format for date in log messages

  '''
  # to set the handler of the root logging object, we need to do setup
  # manually rather than using basicConfig
  root = logging.getLogger()
  root.setLevel(level)
  formatter = logging.Formatter(format, datefmt)
  handler = StdoutStderrHandler(threshold=threshold)
  handler.setLevel(level)
  handler.setFormatter(formatter)
  root.addHandler(handler)
