"""Nicer log formatting with colours.

Code copied from Tornado, Apache licensed.
"""
# Copyright 2012 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import logging
import sys

try:
    import curses
except ImportError:
    curses = None


def _stderr_supports_color():
    color = False
    if curses and hasattr(sys.stderr, 'isatty') and sys.stderr.isatty():
        try:
            curses.setupterm()
            if curses.tigetnum("colors") > 0:
                color = True
        except Exception:
            pass
    return color


class LogFormatter(logging.Formatter):
    """Log formatter with colour support
    """
    DEFAULT_COLORS = {
        logging.INFO: 2,  # Green
        logging.WARNING: 3,  # Yellow
        logging.ERROR: 1,  # Red
        logging.CRITICAL: 1,
    }

    def __init__(self, color=True, datefmt=None):
        r"""
        :arg bool color: Enables color support.
        :arg string fmt: Log message format.
        It will be applied to the attributes dict of log records. The
        text between ``%(color)s`` and ``%(end_color)s`` will be colored
        depending on the level if color support is on.
        :arg dict colors: color mappings from logging level to terminal color
        code
        :arg string datefmt: Datetime format.
        Used for formatting ``(asctime)`` placeholder in ``prefix_fmt``.
        .. versionchanged:: 3.2
        Added ``fmt`` and ``datefmt`` arguments.
        """
        logging.Formatter.__init__(self, datefmt=datefmt)
        self._colors = {}
        if color and _stderr_supports_color():
            # The curses module has some str/bytes confusion in
            # python3. Until version 3.2.3, most methods return
            # bytes, but only accept strings. In addition, we want to
            # output these strings with the logging module, which
            # works with unicode strings. The explicit calls to
            # unicode() below are harmless in python2 but will do the
            # right conversion in python 3.
            fg_color = (curses.tigetstr("setaf") or
                        curses.tigetstr("setf") or "")

            for levelno, code in self.DEFAULT_COLORS.items():
                self._colors[levelno] = str(
                    curses.tparm(fg_color, code), "ascii")
            self._normal = str(curses.tigetstr("sgr0"), "ascii")

            scr = curses.initscr()
            self.termwidth = scr.getmaxyx()[1]
            curses.endwin()
        else:
            self._normal = ''
            # Default width is usually 80, but too wide is
            # worse than too narrow
            self.termwidth = 70

    def formatMessage(self, record):
        mlen = len(record.message)
        right_text = '{initial}-{name}'.format(initial=record.levelname[0],
                                               name=record.name)
        if mlen + len(right_text) < self.termwidth:
            space = ' ' * (self.termwidth - (mlen + len(right_text)))
        else:
            space = '  '

        if record.levelno in self._colors:
            start_color = self._colors[record.levelno]
            end_color = self._normal
        else:
            start_color = end_color = ''

        return record.message + space + start_color + right_text + end_color


def enable_colourful_output(level=logging.INFO):
    handler = logging.StreamHandler()
    handler.setFormatter(LogFormatter())
    logging.root.addHandler(handler)
    logging.root.setLevel(level)
