# -*- coding:utf-8 -*-
#
# 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)
