# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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 re

LIGHT = 010

ansi_CSI = '\033['
ansi_seq = re.compile(re.escape(ansi_CSI) + r'(?P<params>[\x20-\x3f]*)(?P<final>[\x40-\x7e])')
ansi_cmd_SGR = 'm'  # set graphics rendition

color_defs = (
    (000, 'k', 'black'),
    (001, 'r', 'dark red'),
    (002, 'g', 'dark green'),
    (003, 'w', 'brown', 'dark yellow'),
    (004, 'b', 'dark blue'),
    (005, 'm', 'dark magenta', 'dark purple'),
    (006, 'c', 'dark cyan'),
    (007, 'n', 'light grey', 'light gray', 'neutral', 'dark white'),
    (010, 'B', 'dark grey', 'dark gray', 'light black'),
    (011, 'R', 'red', 'light red'),
    (012, 'G', 'green', 'light green'),
    (013, 'Y', 'yellow', 'light yellow'),
    (014, 'B', 'blue', 'light blue'),
    (015, 'M', 'magenta', 'purple', 'light magenta', 'light purple'),
    (016, 'C', 'cyan', 'light cyan'),
    (017, 'W', 'white', 'light white'),
)

colors_by_num = {}
colors_by_letter = {}
colors_by_name = {}
letters_by_num = {}

for colordef in color_defs:
    colorcode = colordef[0]
    colorletter = colordef[1]
    colors_by_num[colorcode] = nameset = set(colordef[2:])
    colors_by_letter[colorletter] = colorcode
    letters_by_num[colorcode] = colorletter
    for c in list(nameset):
        # equivalent names without spaces
        nameset.add(c.replace(' ', ''))
    for c in list(nameset):
        # with "bright" being an alias for "light"
        nameset.add(c.replace('light', 'bright'))
    for c in nameset:
        colors_by_name[c] = colorcode

class ColoredChar:
    def __init__(self, c, colorcode):
        self.c = c
        self._colorcode = colorcode

    def colorcode(self):
        return self._colorcode

    def plain(self):
        return self.c

    def __getattr__(self, name):
        return getattr(self.c, name)

    def ansi_color(self):
        clr = str(30 + (07 & self._colorcode))
        if self._colorcode & 010:
            clr = '1;' + clr
        return clr

    def __str__(self):
        return "<%s '%r'>" % (self.__class__.__name__, self.colored_repr())
    __repr__ = __str__

    def colored_version(self):
        return '%s0;%sm%s%s0m' % (ansi_CSI, self.ansi_color(), self.c, ansi_CSI)

    def colored_repr(self):
        if self.c == "'":
            crepr = r"\'"
        elif self.c == '"':
            crepr = self.c
        else:
            crepr = repr(self.c)[1:-1]
        return '%s0;%sm%s%s0m' % (ansi_CSI, self.ansi_color(), crepr, ansi_CSI)

    def colortag(self):
        return lookup_letter_from_code(self._colorcode)

class ColoredText:
    def __init__(self, source=''):
        if isinstance(source, basestring):
            plain, colors = self.parse_ansi_colors(source)
            self.chars = map(ColoredChar, plain, colors)
        else:
            # expected that source is an iterable of ColoredChars (or duck-typed as such)
            self.chars = tuple(source)

    def splitlines(self):
        lines = [[]]
        for c in self.chars:
            if c.plain() == '\n':
                lines.append([])
            else:
                lines[-1].append(c)
        return [self.__class__(line) for line in lines]

    def plain(self):
        return ''.join([c.plain() for c in self.chars])

    def __getitem__(self, index):
        return self.chars[index]

    @classmethod
    def parse_ansi_colors(cls, source):
        # note: strips all control sequences, even if not SGRs.
        colors = []
        plain = ''
        last = 0
        curclr = 0
        for match in ansi_seq.finditer(source):
            prevsegment = source[last:match.start()]
            plain += prevsegment
            colors.extend([curclr] * len(prevsegment))
            if match.group('final') == ansi_cmd_SGR:
                try:
                    curclr = cls.parse_sgr_param(curclr, match.group('params'))
                except ValueError:
                    pass
            last = match.end()
        prevsegment = source[last:]
        plain += prevsegment
        colors.extend([curclr] * len(prevsegment))
        return ''.join(plain), colors

    @staticmethod
    def parse_sgr_param(curclr, paramstr):
        oldclr = curclr
        args = map(int, paramstr.split(';'))
        for a in args:
            if a == 0:
                curclr = lookup_colorcode('neutral')
            elif a == 1:
                curclr |= LIGHT
            elif 30 <= a <= 37:
                curclr = (curclr & LIGHT) | (a - 30)
            else:
                # not supported renditions here; ignore for now
                pass
        return curclr

    def __repr__(self):
        return "<%s '%s'>" % (self.__class__.__name__, ''.join([c.colored_repr() for c in self.chars]))
    __str__ = __repr__

    def __iter__(self):
        return iter(self.chars)

    def colored_version(self):
        return ''.join([c.colored_version() for c in self.chars])

    def colortags(self):
        return ''.join([c.colortag() for c in self.chars])

def lookup_colorcode(name):
    return colors_by_name[name]

def lookup_colorname(code):
    return colors_by_num.get(code, 'Unknown-color-0%o' % code)

def lookup_colorletter(letter):
    return colors_by_letter[letter]

def lookup_letter_from_code(code):
    letr = letters_by_num.get(code, ' ')
    if letr == 'n':
        letr = ' '
    return letr
