import six
import ujson as json
from logging import Formatter as LoggingFormatter
from logging import LogRecord
from datetime import datetime, tzinfo, timedelta

from .. import level
from .base import UberFormatter


class ConcatFormatter(UberFormatter):
    msg_fmt = u"{0}{operator}{1}"
    line_fmt = u"{message}{delimiter}{parameters}"
    color_fmt = "{color}{text}\x1b[0m"
    log_color_map = {
        level.DEBUG: '\x1b[32m',
        level.INFO: '\x1b[0m',
        level.WARNING: '\x1b[33m',
        level.ERROR: '\x1b[31m',
        level.CRITICAL: '\x1b[35m',
    }

    def __init__(self, operator=":",
                 delimiter=";",
                 log_in_color=False,
                 **kwargs):
        """
        Initialize the handler.
        """
        super(ConcatFormatter, self).__init__(**kwargs)
        # https://docs.python.org/2/library/logging.html#logrecord-attributes
        self.delimiter = delimiter
        self.operator = operator
        self.color = log_in_color

    @profile
    def _uber_message(self, record):
        # get the none formatted message (not getMessage())
        # might be a class that represents a string,
        # for example: StringifiableFromEvent in twisted
        message = record.msg \
            if isinstance(record.msg, six.string_types) \
            else unicode(record.msg)

        if record.uber_extra:
            if self.parse_text:
                message = message.format(**record.uber_extra)

            params = [self.msg_fmt.format(operator=self.operator, *(key, val))
                      for key, val in six.iteritems(record.uber_extra)
                      if self.include_keywords or key not in record.uber_kws]

            if params:
                paramstring = self.delimiter.join(params)
                message = self.line_fmt.format(message=message,
                                               delimiter=self.delimiter,
                                               parameters=paramstring)

        if self.color:
            color = self.log_color_map[record.levelno]
            message = self.color_fmt.format(color=color, text=message)

        return message

    def format(self, record):
        record.uber_message = self._uber_message(record) \
            if self.uber_record(record) \
            else record.getMessage()

        return super(ConcatFormatter, self).format(record)

@@ -153,16 +153,65 @@
 imedelta
+%0Afrom inspect import currentframe as currentframe
 %0A%0Afrom .
@@ -1391,17 +1391,16 @@
 rd.msg)%0A
-%0A
         
@@ -2034,25 +2034,24 @@
 string)%0A
-%0A
         
 if self.
@@ -2046,27 +2046,65 @@
     
-if self.color:%0A    
+return message%0A%0A    def colorize(self, text, log_level):%0A
     
@@ -2138,22 +2138,17 @@
 map%5B
-record.
+log_
 level
-no
 %5D%0A  
@@ -2149,37 +2149,30 @@
 el%5D%0A        
-    message =
+return
  self.color_
@@ -2204,40 +2204,521 @@
 ext=
-message)%0A%0A        return message
+text)%0A%0A    def formatException(self, exc_info):%0A        exc_text = super(ConcatFormatter, self).formatException(exc_info)%0A        if self.color:%0A            frame = currentframe()%0A            levelno = frame.f_back.f_locals%5B%22record%22%5D.levelno%0A            # why delete the frame?%0A            # VERSION: 2 or 3%0A            # https://docs.python.org/VERSION/library/inspect.html#the-interpreter-stack%0A            del frame%0A            exc_text = self.colorize(text=exc_text, log_level=levelno)%0A        return exc_text
 %0A%0A  
@@ -2753,28 +2753,16 @@
         
-record.uber_
 message 
@@ -2872,16 +2872,155 @@
 sage()%0A%0A
+        if self.color:%0A            message = self.colorize(text=message, log_level=record.levelno)%0A%0A        record.uber_message = message%0A%0A
         

Fix bug that prevented exceptions from being colored