#
# 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
from git_config import GitConfig

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 += ';'
        need_sep = True

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


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

    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

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

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

  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 colorer(self, opt=None, fg=None, bg=None, attr=None):
    if self._on:
      c = self._parse(opt, fg, bg, attr)
      def f(fmt, *args):
        str = fmt % args
        return ''.join([c, str, RESET])
      return f
    else:
      def f(fmt, *args):
        return fmt % args
      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.trim().lowercase()
    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)
