# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function

import os
import sys
import logging

from logging import Formatter, StreamHandler, DEBUG, INFO

__all__ = (
    'init',
)

RESET_TERM = '\033[0;m'

COLOR_CODES = {
    'red': 31,
    'green': 32,
    'yellow': 33,
    'blue': 34,
    'magenta': 35,
    'cyan': 36,
    'white': 37,
    'bgred': 41,
    'bggrey': 100,
}

LEVEL_COLORS = {
    'DEBUG': 'blue',
    'WARNING': 'yellow',
    'ERROR': 'red',
    'CRITICAL': 'bgred',
}

DRYRUN = 25
DIFF = 15


def ansi(color, text):
    """Wrap text in an ansi escape sequence"""
    code = COLOR_CODES[color]
    return '\033[1;{0}m{1}{2}'.format(code, text, RESET_TERM)


class ANSIFormatter(Formatter):
    """
    Convert a `logging.LogRecord' object into colored text, using ANSI
    escape sequences.
    """
    def format(self, record):
        msg = record.getMessage()
        if record.levelname == 'INFO':
            return ansi('cyan', '-> ') + msg
        elif record.levelname == 'DRYRUN':
            return ansi('magenta', 'dryrun-> ') + msg
        elif record.levelname == 'DIFF':
            if msg.startswith('+'):
                return ansi('green', msg)
            elif msg.startswith('-'):
                return ansi('red', msg)
            else:
                return msg
        else:
            color = LEVEL_COLORS.get(record.levelname, 'white')
            return ansi(color, record.levelname.lower()) + ': ' + msg


class TextFormatter(Formatter):
    """
    Convert a `logging.LogRecord' object into text.
    """
    def format(self, record):
        if not record.levelname or record.levelname in ('INFO', 'DIFF'):
            return record.getMessage()
        elif record.levelname == 'DRYRUN':
            return 'dryrun-> {0}'.format(record.getMessage())
        else:
            return record.levelname.lower() + ': ' + record.getMessage()


class BumprLogger(logging.Logger):
    def dryrun(self, *args):
        self.log(DRYRUN, *args)

    def diff(self, *args):
        self.log(DIFF, *args)


def declare():
    logging.addLevelName(DRYRUN, 'DRYRUN')
    logging.addLevelName(DIFF, 'DIFF')
    logging.setLoggerClass(BumprLogger)


def init(level=INFO):
    declare()

    logger = logging.getLogger()
    handler = StreamHandler()

    if (os.isatty(sys.stdout.fileno()) and not sys.platform.startswith('win')):
        fmt = ANSIFormatter()
    else:
        fmt = TextFormatter()
    handler.setFormatter(fmt)
    logger.addHandler(handler)

    if level:
        logger.setLevel(level)


if __name__ == '__main__':  # pragma: no cover
    init(level=DEBUG)

    logger = logging.getLogger(__name__)
    logger.debug('debug')
    logger.dryrun('dryrun')
    logger.diff('diff')
    logger.diff('+ diff')
    logger.diff('- diff')
    logger.info('info')
    logger.warning('warning')
    logger.error('error')
    logger.critical('critical')
