# Copyright (C) 2008 The Android Open Source Project
#
# 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 os
import sys

import pager


COLORS = {
    None: -1,
    "normal": -1,
    "black": 0,
    "red": 1,
    "green": 2,
    "yellow": 3,
    "blue": 4,
    "magenta": 5,
    "cyan": 6,
    "white": 7,
}

ATTRS = {None: -1, "bold": 1, "dim": 2, "ul": 4, "blink": 5, "reverse": 7}

RESET = "\033[m"


def is_color(s):
    return s in COLORS


def is_attr(s):
    return s in ATTRS


def _Color(fg=None, bg=None, attr=None):
    fg = COLORS[fg]
    bg = COLORS[bg]
    attr = ATTRS[attr]

    if attr >= 0 or fg >= 0 or bg >= 0:
        need_sep = False
        code = "\033["

        if attr >= 0:
            code += chr(ord("0") + attr)
            need_sep = True

        if fg >= 0:
            if need_sep:
                code += ";"
            need_sep = True

            if fg < 8:
                code += "3%c" % (ord("0") + fg)
            else:
                code += "38;5;%d" % fg

        if bg >= 0:
            if need_sep:
                code += ";"

            if bg < 8:
                code += "4%c" % (ord("0") + bg)
            else:
                code += "48;5;%d" % bg
        code += "m"
    else:
        code = ""
    return code


DEFAULT = None


def SetDefaultColoring(state):
    """Set coloring behavior to |state|.

    This is useful for overriding config options via the command line.
    """
    if state is None:
        # Leave it alone -- return quick!
        return

    global DEFAULT
    state = state.lower()
    if state in ("auto",):
        DEFAULT = state
    elif state in ("always", "yes", "true", True):
        DEFAULT = "always"
    elif state in ("never", "no", "false", False):
        DEFAULT = "never"


class Coloring(object):
    def __init__(self, config, section_type):
        self._section = "color.%s" % section_type
        self._config = config
        self._out = sys.stdout

        on = DEFAULT
        if on is None:
            on = self._config.GetString(self._section)
            if on is None:
                on = self._config.GetString("color.ui")

        if on == "auto":
            if pager.active or os.isatty(1):
                self._on = True
            else:
                self._on = False
        elif on in ("true", "always"):
            self._on = True
        else:
            self._on = False

    def redirect(self, out):
        self._out = out

    @property
    def is_on(self):
        return self._on

    def write(self, fmt, *args):
        self._out.write(fmt % args)

    def flush(self):
        self._out.flush()

    def nl(self):
        self._out.write("\n")

    def printer(self, opt=None, fg=None, bg=None, attr=None):
        s = self
        c = self.colorer(opt, fg, bg, attr)

        def f(fmt, *args):
            s._out.write(c(fmt, *args))

        return f

    def nofmt_printer(self, opt=None, fg=None, bg=None, attr=None):
        s = self
        c = self.nofmt_colorer(opt, fg, bg, attr)

        def f(fmt):
            s._out.write(c(fmt))

        return f

    def colorer(self, opt=None, fg=None, bg=None, attr=None):
        if self._on:
            c = self._parse(opt, fg, bg, attr)

            def f(fmt, *args):
                output = fmt % args
                return "".join([c, output, RESET])

            return f
        else:

            def f(fmt, *args):
                return fmt % args

            return f

    def nofmt_colorer(self, opt=None, fg=None, bg=None, attr=None):
        if self._on:
            c = self._parse(opt, fg, bg, attr)

            def f(fmt):
                return "".join([c, fmt, RESET])

            return f
        else:

            def f(fmt):
                return fmt

            return f

    def _parse(self, opt, fg, bg, attr):
        if not opt:
            return _Color(fg, bg, attr)

        v = self._config.GetString("%s.%s" % (self._section, opt))
        if v is None:
            return _Color(fg, bg, attr)

        v = v.strip().lower()
        if v == "reset":
            return RESET
        elif v == "":
            return _Color(fg, bg, attr)

        have_fg = False
        for a in v.split(" "):
            if is_color(a):
                if have_fg:
                    bg = a
                else:
                    fg = a
            elif is_attr(a):
                attr = a

        return _Color(fg, bg, attr)
