# 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)
