#-*- coding: utf-8 -*-

# Copyright 2012-2014 Calculate Ltd. http://www.calculate-linux.org
#
#  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 sys
import termios
import os
import re
from fcntl import ioctl
from array import array
import threading

from calculate.core.client.progressbar import Bar, Percentage, ETA, ProgressBar
from calculate.lib.cl_progressbar import ClProgressDialog, ClMessageBox
from calculate.lib.utils.colortext import get_terminal_print, \
    convert_xml_to_terminal
from calculate.lib.utils.colortext.palette import TextState
from calculate.lib.utils.text import tableReport
from calculate.lib.utils.files import getch
from calculate.lib.utils.colortext.converter import XmlConverter
from calculate.lib.utils.colortext.output import BaseOutput
from calculate.lib.cl_print import color_print
from calculate.lib.datavars import VariableError
from calculate.lib.cl_lang import setLocalTranslate

from methods_func import get_method_argparser, collect_object, \
    check_result_msg, get_param_pwd, _print
from api_types import ViewInfo
from cert_cmd import parse
from methods_func import getErrorOnParam, GotErrorField
from func import shortTraceback, CommonMethods


setLocalTranslate('cl_core3', sys.modules[__name__])
from itertools import cycle
import time


class Spinner(threading.Thread):
    def __init__(self, *args, **kwargs):
        self.__halt = threading.Event()
        self.__main_thread = threading.currentThread()
        threading.Thread.__init__(self, *args, **kwargs)
        self.start()

    def run(self):
        sys.stdout.write(" |")
        for c in cycle('/-\|'):
            sys.stdout.write('\b' + c)
            sys.stdout.flush()
            self.__halt.wait(0.2)
            sys.stdout.flush()
            if self.__halt.is_set():
                sys.stdout.write('\b\b  \b\b')
                return
            if not self.__main_thread.is_alive():
                return

    def stop(self):
        self.__halt.set()
        self.join()


class replaceClass():
    method_status = 2

    def startprocess(self, sid, target=None, method=None, method_name=None, \
                     auto_delete=False, args_proc={}):
        """ start process """
        if "LANG" in os.environ:
            curThread = threading.currentThread()
            curThread.lang = os.environ["LANG"]
        com = target(self.no_progress, self.gui_progress, self.gui_warning,
                     self.no_questions)
        if len(com.__class__.__bases__) > 1 and \
                hasattr(com.__class__.__bases__[1], '__init__'):
            com.__class__.__bases__[1].__init__(com)
        self.method_status = 0 if getattr(com, method)(*args_proc) else 1
        return 0

    class Common(CommonMethods):
        """ class to interact with the processes """
        reClearTags = re.compile("<.*?>")

        def __init__(self, no_progress, gui_progress, gui_warning,
                     no_questions):
            self.pid = 0
            self.Num = 100000
            self.color_print = color_print()

            self.no_progress = no_progress
            self.gui_progress = gui_progress
            self.gui_warning = gui_warning
            self.progress = None
            self.progressbar = None
            self.last_progress_msg = ''
            self.error = []
            self.warning = []
            self.no_questions = no_questions
            self.currentTaskMessage = ""
            self.spinner = None
            self.terminal_print = \
                get_terminal_print(self.color_print.defaultPrint)

        def writeFile(self):
            pass

        def setProgress(self, perc, short_message=None, long_message=None):
            if self.no_progress:
                self.progress = perc
                return
            if perc >= 100 or perc < 0:
                if self.progressbar and not self.progressbar.finished:
                    if not self.gui_progress:
                        self.progressbar.finish()
            self.last_progress_msg = self.print_progressbar(perc,
                                                            short_message,
                                                            long_message,
                                                            last_msg=self.last_progress_msg)

        def print_progressbar(self, percent, short_message, long_message,
                              last_msg=None, error=False):
            if not self.progressbar:
                return
            if long_message:
                if self.gui_progress:
                    self.progressbar.setTextLabel(long_message)
                    self.progressbar.setMaximum(100)
                    self.progressbar.setTextVisible(True)
                    if percent == 100:
                        self.progressbar.setValue(99)
                    self.progressbar.setValue(percent)
                else:
                    if last_msg != long_message:
                        cout_progress()
                        for line in long_message.splitlines():
                            self.color_print.printSUCCESS(line)
                    self.progressbar.update(percent)
                return long_message
            elif short_message:
                if self.gui_progress:
                    self.progressbar.setTextLabel(short_message)
                    self.progressbar.setMaximum(100)
                    self.progressbar.setTextVisible(True)
                    if percent == 100:
                        self.progressbar.setValue(99)
                    self.progressbar.setValue(percent)
                else:
                    if last_msg != short_message:
                        cout_progress()
                        for line in short_message.splitlines():
                            self.color_print.printSUCCESS(line)
                    self.progressbar.update(percent)
                return short_message
            else:
                if self.gui_progress:
                    self.progressbar.setMaximum(100)
                    self.progressbar.setTextVisible(True)
                    if percent == 100:
                        self.progressbar.setValue(99)
                    self.progressbar.setValue(percent)
                else:
                    self.progressbar.update(percent)
                return last_msg

        def setStatus(self, stat):
            pass

        def setData(self, dat):
            self.data_list = dat

        def getStatus(self):
            pass

        def getProgress(self):
            if self.no_progress:
                return self.progress
            if self.progressbar:
                if self.gui_progress:
                    return self.progressbar.value()
                else:
                    return self.progressbar.currval
            return 100

        def addProgress(self, message=""):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None

            self.nextLine(clearCurrent=False)
            if self.no_progress:
                self.progress = 0
                return
            if self.gui_progress:
                if ClProgressDialog:
                    if not self.progressbar:
                        self.progressbar = ClProgressDialog()
                        self.progressbar.setCancelButton(None)
                        self.progressbar.adjustSize()
                        self.progressbar.setWindowTitle("")
                        self.progressbar.setAutoClose(False)
                        self.progressbar.setAutoReset(False)
                    self.progressbar.setLabelText(message.decode('utf-8'))
                    self.progressbar.setMaximum(0)
                    self.progressbar.setTextVisible(False)
                else:
                    self.progressbar = None
            else:
                widgets = ['', '', Bar(), '', Percentage(), ' ', ETA()]
                self.progressbar = ProgressBar(widgets=widgets, maxval=100)
                self.progressbar.start()
                self.progress = 0
            self.addMessage(type='progress', id=id)

        def printTable(self, table_name, head, body, fields=None, \
                       onClick=None, addAction=None):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None
            self.printSUCCESS(message=table_name)
            print printTable(body, head)

        def addMessage(self, type='normal', message=None, id=None,
                       onlyShow=None):
            self.printSUCCESS(message, onlyShow=onlyShow)

        def printDefault(self, message='', onlyShow=None):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None
            if onlyShow == "gui":
                return
            message = self.processTags(message)
            self.color_print.defaultPrint(message + "\n")

        def printPre(self, message='', onlyShow=None):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None
            if onlyShow == "gui":
                return
            self.nextLine()
            self.printDefault(message)

        def processTags(self, s):
            """
            Выполнить текстовое преобразование
            """
            return convert_xml_to_terminal(s).replace("&nbsp;", " ")

        def cleanTags(self, s):
            """
            Убрать тэги
            """
            converter = XmlConverter(BaseOutput())
            return converter.transform(s).replace("&nbsp;", " ")

        def printSUCCESS(self, message='', onlyShow=None):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None
            if onlyShow == "gui":
                return
            if message:
                self.nextLine()
                if self.progressbar and not self.gui_progress:
                    if not self.progressbar.finished:
                        cout_progress()
                        for line in message.splitlines():
                            self.color_print.printSUCCESS(
                                self.processTags(line))
                        return
                for line in message.splitlines():
                    self.color_print.printSUCCESS(self.processTags(line))
                    #self.spinner = Spinner()

        def printWARNING(self, message='', onlyShow=None):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None
            if onlyShow == "gui":
                return
            self.nextLine()
            if self.progressbar and not self.no_progress \
                    and not self.gui_progress:
                if not self.progressbar.finished:
                    cout_progress()
                    for line in message.splitlines():
                        line = self.processTags(line)
                        self.color_print.printWARNING(line)
                    return
            if message:
                for line in message.splitlines():
                    line = self.processTags(line)
                    self.color_print.printWARNING(line)
            if message:
                self.warning.append(message)

        def printERROR(self, message='', onlyShow=None):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None
            if onlyShow == "gui":
                return
            self.nextLine()
            perc = self.getProgress()
            if perc == 0:
                self.setProgress(100)
            elif self.getProgress() > 0:
                # finish progress
                #self.setProgress(0 - self.getProgress())
                self.setProgress(100)
            else:
                #self.setProgress(-100)
                self.setProgress(perc)
            if message:
                for line in message.splitlines():
                    line = self.processTags(line)
                    self.color_print.printERROR(line)
            if message:
                self.error.append(message)

        def startTask(self, message, progress=False, num=1):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None
            self.nextLine()
            self.currentTaskMessage = self.cleanTags(message)
            message = self.processTags(message)
            self.color_print.printSUCCESS(message, printBR=False)
            self.color_print.defaultPrint(" ...")
            if progress:
                self.addProgress(message)
            elif not self.spinner:
                self.spinner = Spinner()

        def setTaskNumber(self, number=None):
            pass

        def _printOK(self):
            self.terminal_print('\r')
            self.terminal_print.right(self.color_print.getconsolewidth()-7)
            self.terminal_print.bold.foreground(TextState.Colors.BLUE)("[ ")
            self.terminal_print.bold.foreground(TextState.Colors.GREEN)("ok")
            self.terminal_print.bold.foreground(TextState.Colors.BLUE)(" ]")
            self.terminal_print("\n")

        def _printBAD(self):
            self.terminal_print('\r')
            self.terminal_print.right(self.color_print.getconsolewidth()-7)
            self.terminal_print.bold.foreground(TextState.Colors.BLUE)("[ ")
            self.terminal_print.bold.foreground(TextState.Colors.RED)("!!")
            self.terminal_print.bold.foreground(TextState.Colors.BLUE)(" ]")
            self.terminal_print("\n")

        def _printSkip(self):
            self.terminal_print('\r')
            self.terminal_print.right(self.color_print.getconsolewidth()-9)
            self.terminal_print.bold.foreground(TextState.Colors.BLUE)("[ ")
            self.terminal_print.bold.foreground(TextState.Colors.YELLOW)("skip")
            self.terminal_print.bold.foreground(TextState.Colors.BLUE)(" ]")
            self.terminal_print("\n")

        def endTask(self, result=None, progress_message=None):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None
            self.setProgress(100, progress_message)
            if self.progressbar and self.progressbar.finished:
                self.terminal_print.up(1).clear_line("")
                self.terminal_print.up(1)("")
                self.progressbar = None

            # если result - сообщение
            if self.currentTaskMessage:
                self.displayResult(result)
                self.currentTaskMessage = ""

        def displayResult(self, result):
            func_map = {"skip": self._printSkip,
                        False: self._printBAD}
            func_map.get(result, self._printOK)()

        def nextLine(self, clearCurrent=True):
            if self.currentTaskMessage:
                self.color_print.defaultPrint('\n')
                if clearCurrent:
                    self.currentTaskMessage = ""

        def askConfirm(self, message, default="yes"):
            if self.no_questions:
                return default
            print
            while True:
                try:
                    Colors = TextState.Colors
                    _print = get_terminal_print()
                    if default in "yes":
                        yes_color, no_color = Colors.GREEN, Colors.LIGHT_RED
                    else:
                        yes_color, no_color = Colors.LIGHT_RED, Colors.GREEN
                    yes = _print.foreground(yes_color).bold("Yes")
                    no = _print.foreground(no_color).bold("No")
                    white_message = _print.foreground(Colors.WHITE).bold(
                        message)
                    ask = raw_input(white_message + ' (%s/%s): ' % (yes, no))
                except KeyboardInterrupt:
                    ask = 'no'
                    print
                if ask.lower() in ['n', 'no']:
                    return "no"
                if ask.lower() in ['y', 'yes']:
                    return "yes"
                if ask == '':
                    return default

        def isInteractive(self):
            """
            Check interactive ability
            """
            return sys.stdin.isatty()

        def askChoice(self, message, answers=[("yes", "Yes"), ("no", "No")]):
            Colors = TextState.Colors
            _print = get_terminal_print()
            colorPrint = color_print()
            print
            # ability answer by first letter
            FIRSTLETTER = 0
            VALUE, COMMENT = 0, 1
            answerByChar = map(lambda x: x[VALUE][FIRSTLETTER], answers)
            if filter(lambda x: answerByChar.count(x) > 1, answerByChar):
                useGetChar = False
            else:
                useGetChar = True
            message = _print.foreground(Colors.WHITE).bold(message)

            while True:
                outMessage = message + ' (%s): ' % \
                             ("/".join(map(lambda x: \
                                               "%s[%s]" % (x[COMMENT], x[VALUE][
                                                   FIRSTLETTER]),
                                           answers)))
                CTRC_C = chr(3)
                if useGetChar:
                    colorPrint.defaultPrint(outMessage)
                    ask = getch()
                    if ask == CTRC_C:
                        print
                        raise KeyboardInterrupt
                    print
                else:
                    try:
                        ask = raw_input(outMessage)
                    except KeyboardInterrupt:
                        print
                        raise KeyboardInterrupt
                ask = ask.lower()
                likeAnswers = filter(lambda x: x[VALUE].startswith(ask),
                                     answers)
                if not likeAnswers:
                    colorPrint.printERROR(_('The answer is uncertain'))
                    continue
                if len(likeAnswers) == 1:
                    return likeAnswers[VALUE][FIRSTLETTER]
                else:
                    colorPrint.printERROR(_('Ambiguous answer:') +
                                          ",".join(map(lambda x: x[COMMENT],
                                                       likeAnswers)))

        def askQuestion(self, message):
            print
            return raw_input(message + ":")

        def askPassword(self, message, twice=False):
            from calculate.lib.utils.common import getpass

            if os.readlink('/proc/self/fd/0') == '/dev/console':
                os.system('chvt 1 &>/dev/null')
            text1 = "%s:" % message
            if not twice:
                return getpass.getpass(text1)
            if twice:
                text2 = _('Repeat: ')
                pass1 = 'password'
                pass2 = 'repeat'
            try:
                while pass1 != pass2:
                    pass1 = getpass.getpass(text1)
                    pass2 = getpass.getpass(text2)
                    if pass1 != pass2:
                        print _('Passwords do not match')
            except KeyboardInterrupt:
                return None
            passwd = pass1 if (pass1 and pass1 == pass2) else None
            return passwd

        def beginFrame(self, message=None):
            self.printSUCCESS(message=message)

        def endFrame(self):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None

            self.addMessage(type='endFrame')
            if self.gui_progress and self.progressbar:
                self.progressbar.quit()
            if self.warning and not self.error and self.gui_warning:
                ClMessageBox().warning(
                    ("\n".join(self.warning)).decode('utf-8'))
            if self.error and self.gui_progress:
                if self.warning and self.gui_warning:
                    error = "\n".join(self.warning + self.error)
                else:
                    error = "\n".join(self.error)
                ClMessageBox().critical(error.decode('utf-8'))

        def startGroup(self, message):
            _print = get_terminal_print()
            self.printDefault(
                _print.foreground(TextState.Colors.WHITE).bold(message))
            #self.addMessage(type='startGroup', message=message)

        def endGroup(self):
            if self.spinner:
                self.spinner.stop()
                self.spinner = None
            pass


def cout_progress(string=None):
    try:
        h, w = array('h', ioctl(sys.stderr, termios.TIOCGWINSZ, '\0' * 8))[:2]
    except IOError:
        return
    sys.stdout.write('\r' + (' ' * (w)))
    if string:
        sys.stdout.write('\r' + string)
    else:
        sys.stdout.write('\r')
    sys.stdout.flush()


def local_method(metaclass, args, unknown_args):
    """
    Call method from metaclass, check method existing.

    Generate help, for method, run method by 'call_method'.
    """
    import os

    sym_link = os.path.basename(sys.argv[0])
    if sym_link != 'cl-core':
        if sym_link in metaclass.Dec.conMethods.keys():
            args.method = metaclass.Dec.conMethods[sym_link][0]
        else:
            _print(_("Method not found for %s") % sym_link)
            sys.exit(1)

    if args.list_methods:
        keys = metaclass.Dec.conMethods.keys()
        keys.sort()
        for key in keys:
            print metaclass.Dec.conMethods[key][0], ' - ', \
                metaclass.Dec.conMethods[key][2]
        return 0

    colorPrint = color_print()
    metaObject = metaclass()
    method_name = args.method
    method_view_name = method_name + '_view'
    if args.method and args.help:
        view_obj = ViewInfo()
        view_obj.step = None
        view_obj.expert = True
        view_obj.brief = None
        view_obj.onlyhelp = True
        try:
            view = getattr(metaObject, method_view_name)(0, view_obj)
        except AttributeError:
            colorPrint.printERROR(_('Method not found: ') + method_view_name)
            return 1
        try:
            method_parser = get_method_argparser(view, args, cl_core=True)
        except Exception as e:
            #import traceback
            #for i in apply(traceback.format_exception, sys.exc_info()):
            #    sys.stderr.write(i)
            #sys.stderr.flush()
            metaObject.clear_cache(0, method_name)
            return 1
        method_parser.print_help()
    else:
        try:
            call_method(metaObject, args, unknown_args, colorPrint)
            metaObject.clear_cache(0, method_name)
            return metaObject.method_status
        except (ValueError) as e:
            colorPrint.printERROR(str(e))
            #colorPrint.printERROR(shortTraceback(*sys.exc_info()))
        except (KeyboardInterrupt, EOFError):
            colorPrint.printERROR(_('Manually interrupted'))
        except (GotErrorField,) as e:
            pass
        except Exception as e:
            colorPrint.printERROR(shortTraceback(*sys.exc_info()))
            pass
        #            print 'Error: ', e
    metaObject.clear_cache(0, method_name)


def call_method(metaObject, args, unknown_args, colorPrint):
    """
    Function for call method through metaObject and args
    """
    method_name = args.method
    stdin_passwd = args.stdin_passwd
    method_view_name = method_name + '_view'
    metaObject.no_progress = args.no_progress
    metaObject.gui_progress = args.gui_progress
    metaObject.gui_warning = args.gui_warning
    metaObject.no_questions = False
    view_obj = ViewInfo()
    view_obj.step = None
    view_obj.expert = True
    view_obj.brief = None
    view_obj.onlyhelp = True

    try:
        view = getattr(metaObject, method_view_name)(0, view_obj)
    except AttributeError:
        colorPrint.printERROR(_('Method not found: ') + method_name)
        return None
    method_parser = get_method_argparser(view, args, cl_core=True)
    param_object = create_param_object(view)
    try:
        unknown_args = method_parser.fixBoolVariables(unknown_args)
        args, unknown_args = method_parser.parse_known_args(unknown_args)
        no_questions = args.no_questions
        metaObject.no_questions = no_questions
    except SystemExit as e:
        return 1
    except Exception as e:
        import traceback

        for i in apply(traceback.format_exception, sys.exc_info()):
            sys.stderr.write(i)
        sys.stderr.flush()
        raise
    for i in unknown_args:
        if i.startswith('-'):
            if i in parse(True).parse_known_args()[1]:
                _print(_('Unknown parameter'), i)
                return 1
        else:
            _print(_('Unknown argument'), i)
            return 1

    param_object, steps = collect_object(None, param_object, view, args,
                                         stdin_passwd=stdin_passwd)
    if view.has_brief:
        setattr(param_object, 'CheckOnly', True)
        check_res = {}
        while True:
            method_result = getattr(metaObject, method_name)(0, param_object)
            if not method_result:
                print _('Method not available')
                return None

            if method_result[0].type and method_result[0].type != "pid":
                check_res = check_result_msg(method_result, view, check_res,
                                             args)
                if not check_res:
                    return None
                else:
                    param_object = get_param_pwd(check_res, view,
                                                 param_object,
                                                 stdin_passwd=stdin_passwd)
            else:
                break

        view_obj = ViewInfo()
        view_obj.step = None
        view_obj.expert = True
        view_obj.brief = True
        view_obj.onlyhelp = False
        try:
            view = getattr(metaObject, method_view_name)(0, view_obj)
        except AttributeError:
            colorPrint.printERROR(_('Method not found: ') + method_name)

        print_brief(view, steps.label)
        if not no_questions:
            while True:
                try:
                    ask = raw_input('\n' + _('Run process? (yes/no): '))
                except KeyboardInterrupt:
                    ask = 'no'
                    print
                if ask.lower() in ['n', 'no']:
                    colorPrint.printERROR(_('Manually interrupted'))
                    return None
                if ask.lower() in ['y', 'yes']:
                    break

    setattr(param_object, 'CheckOnly', False)
    try:
        method_result = getattr(metaObject, method_name)(0, param_object)
    except VariableError, e:
        _print(e)
        return None
    if not method_result:
        colorPrint.printERROR(_('method unavailable'))
        return None
    for ReturnedMessage in method_result:
        if ReturnedMessage.type and ReturnedMessage.type != "pid":
            params_text = ''
            for Group in view.groups:
                for field in Group.fields:
                    if field.name == ReturnedMessage.field:
                        params_text += getErrorOnParam(args, field)
            colorPrint.printERROR('\r' + params_text % \
                                  str(ReturnedMessage.message))
            return None
    return method_result


def create_param_object(view):
    param_object = type('collect_object', (object,), {})
    setattr(param_object, 'CheckAll', True)
    setattr(param_object, '_type_info', {})
    for Group in view.groups:
        if not Group.fields:
            continue
        for field in Group.fields:
            setattr(param_object, field.name, None)
            param_object._type_info[field.name] = None
    return param_object


def print_brief(view, brief_label):
    for Group in view.groups:
        if Group.name:
            if not Group.fields:
                continue
        print_brief_group(Group.fields, Group.name)


def print_brief_group(Fields, group_name):
    print_group_flag = False
    #    if group_name:
    #        _print ('\b'+group_name)
    uncompatible_count = 0
    colorPrint = color_print()
    for field in Fields:
        if field.uncompatible:
            uncompatible_count += 1
            continue
        if field.element in ['input', 'openfile']:
            value = field.value if field.value else ''
            if not print_group_flag:
                if group_name:
                    print_group_flag = True
                    _print('\b' + group_name)
            colorPrint.printSUCCESS('%s: %s' % (field.label, value))

        elif field.element in ['combo', 'comboEdit', 'radio', 'file']:
            if field.choice:
                if not field.choice[0]:
                    field.choice.pop(0)
            if field.comments:
                if not field.comments[0]:
                    field.comments.pop(0)
            if field.comments and field.choice:
                if not field.value in field.choice:
                    field.choice.append(field.value)
                value = map(lambda x: field.comments[x] \
                    if len(field.comments) > x else field.choice[x],
                            map(lambda x: field.choice.index(x),
                                filter(lambda x: x in field.choice,
                                       [field.value])))
                value = ', '.join(value)
            else:
                value = field.value if field.value else ''
            if not print_group_flag:
                if group_name:
                    print_group_flag = True
                    _print('\b' + group_name)
            colorPrint.printSUCCESS('%s: %s' % (field.label, value))

        elif field.element in ['multichoice', 'multichoice_add', \
                               'selecttable', 'selecttable_add']:
            if field.choice:
                if not field.choice[0]:
                    field.choice.pop(0)
            if field.comments:
                if not field.comments[0]:
                    field.comments.pop(0)
            if field.listvalue:
                if not field.listvalue[0]:
                    field.listvalue.pop(0)
            if field.choice:
                value = map(lambda x: field.comments[x] \
                    if len(field.comments) > x \
                    else field.choice[x],
                            map(lambda x: field.choice.index(x), \
                                field.listvalue))
            else:
                value = []
            value = ', '.join(value)
            if field.listvalue and not value:
                value = ', '.join(field.listvalue)
            elif not value:
                value = field.value if field.value else ''
            if not print_group_flag:
                if group_name:
                    print_group_flag = True
                    _print('\b' + group_name)
            colorPrint.printSUCCESS('%s: %s' % (field.label, value))

        #        elif field.element == 'label':
        #            print field.label

        elif field.element == 'error':
            if not print_group_flag:
                if group_name:
                    print_group_flag = True
                    _print('\b' + group_name)
            colorPrint.printERROR(field.label)

        elif field.element in ['check', 'check_tristate']:
            if field.value == 'on':
                value = _('yes')
            elif field.value == 'off':
                value = _('no')
            elif field.value == 'auto':
                value = _('auto')
            else:
                value = field.value
            if not print_group_flag:
                if group_name:
                    print_group_flag = True
                    _print('\b' + group_name)
            colorPrint.printSUCCESS('%s: %s' % (field.label, value))

        elif field.element == 'table' and field.type != 'steps':
            head = field.tablevalue.head

            body = []
            for row in field.tablevalue.body:
                if not row[0]:
                    row.pop(0)
                body.append(row)

            # if empty table
            if not filter(None, map(lambda x: x, body)):
                body = [[''] * len(head)]
                res = printTable(body, head)
                sys.stdout.flush()
                sys.stdout.write(res + "\n")
                continue
            ChoiceValue = field.tablevalue.values
            for row in xrange(len(ChoiceValue)):
                if ChoiceValue[row].typefield in ['check', 'check_tristate']:
                    for i in xrange(len(body)):
                        if body[i][row] == 'on':
                            body[i][row] = _('yes')
                        if body[i][row] == 'off':
                            body[i][row] = _('no')
                        if body[i][row] == 'auto':
                            body[i][row] = _('auto')
                if "password" in ChoiceValue[row].typefield:
                    for i in xrange(len(body)):
                        if body[i][row]:
                            body[i][row] = '***'
            data = []
            for body_row in body:
                data.append(map(lambda x: x if x else '', body_row))
            if not print_group_flag:
                if group_name:
                    print_group_flag = True
                    _print('\b' + group_name)
            colorPrint.printSUCCESS(field.label + ': ')
            res = printTable(data, head)
            sys.stdout.flush()
            sys.stdout.write(res + "\n")
        else:
            uncompatible_count += 1


#    if uncompatible_count == len (Fields) and group_name:
#        colorPrint.printSUCCESS(_('Not used'))

class Table(tableReport):
    def __init__(self, *args, **kwargs):
        self.res = []
        tableReport.__init__(self, *args, **kwargs)

    def printFunc(self, s):
        self.res.append(s)

    def printTable(self):
        self.setAutosize()
        self.printReport(printRows=False)
        return "\n".join(self.res)


class Methods(replaceClass.Common, object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Methods, cls).__new__(
                cls, *args, **kwargs)
        return cls._instance

    def __init__(self):
        replaceClass.Common.__init__(self, True, False, False, False)


def printTable(data, header=None):
    try:
        return Table(None, header, data, colSpan=0).printTable()
    except Exception as e:
        print str(e)
        raise

