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