# 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
from typing import Optional

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: Optional[str]) -> None:
    """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"):
        DEFAULT = "always"
    elif state in ("never", "no", "false"):
        DEFAULT = "never"


class Coloring:
    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(f"{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:
                    have_fg = True
                    fg = a
            elif is_attr(a):
                attr = a

        return _Color(fg, bg, attr)
