# -*- coding: utf-8 -*-
{{ header }}

import sys
import json
from collections import OrderedDict
from colorama import init
init()
from colorama import Fore, Style
from tabulate import tabulate
from bambou import NURESTObject


class Printer(object):
    """ Print output for CLI

    """

    TABULATE_FORMAT = "psql"

    @classmethod
    def colorprint(cls, message, color=""):
        """ Print a messsage in a specific color

            Args:
                color: the color of the message
                message: the message to print

        """
        print(color + message + Style.RESET_ALL)

    @classmethod
    def raise_error(cls, message):
        """ Print an error message

            Args:
                message: the message to print

        """
        cls.colorprint("[Error] %s" % message, Fore.RED)
        sys.exit(1)

    @classmethod
    def success(cls, message):
        """ Print a succcess message

            Args:
                message: the message to print

        """
        cls.colorprint("[Success] %s" % message, Fore.GREEN)

    @classmethod
    def warn(cls, message):
        """ Print a warning message

            Args:
                message: the message to print
        """

        cls.colorprint("[WARNING] %s" % message, Fore.YELLOW)

    @classmethod
    def info(cls, message):
        """ Print a log message

            Args:
                message: the message to print
        """

        cls.colorprint("[INFO] %s" % message, Fore.CYAN)

    @classmethod
    def output(cls, data, fields=None, json=False, headers={}):
        """ Print either json or tabulate data

            Args:
                data: the data to display

        """
        if json:
            cls.json(data, fields)
        else:
            cls.tabulate(data, fields, headers)

    ### PRINTING METHODS

    @classmethod
    def json(cls, data, fields):
        """ Print a json version of data

            Args:
                data: something to display

        """
        if isinstance(data, str):
            print(data)

        elif isinstance(data, dict):
            print(json.dumps(data, indent=4))

        elif isinstance(data, list):
            results = []
            for obj in data:
                results.append(cls._object_to_dict(obj, fields))
            print(json.dumps(results, indent=4))

        else:
            print(json.dumps(cls._object_to_dict(data, fields), indent=4))

    @classmethod
    def tabulate(cls, data, fields, headers={}):
        """ Prints a tabulate version of data

            Args:
                data: something to disply

        """
        if isinstance(data, str):
            print tabulate([[data]], tablefmt=Printer.TABULATE_FORMAT)

        elif isinstance(data, dict):
            print tabulate([data], headers=headers, tablefmt=Printer.TABULATE_FORMAT)

        elif isinstance(data, list):
            results = []

            for obj in data:
                if isinstance(obj, NURESTObject):
                    results.append(cls._object_to_dict(obj, fields))
                else:
                    results.append([obj])

            print tabulate(results, headers=headers, tablefmt=Printer.TABULATE_FORMAT)

        else:
            dictionary = cls._object_to_dict(data, fields)
            result = [(key, value) for key, value in dictionary.iteritems()]
            print tabulate(result, headers=headers, tablefmt=Printer.TABULATE_FORMAT)

    @classmethod
    def _object_to_dict(cls, obj, fields=None):
        """ Get object dictionnary with filtered fields

        """
        default_dict = obj.to_dict()

        if fields is None or "ALL" in fields:
            return default_dict

        known_fields = default_dict.keys()
        ordered_dict = OrderedDict()

        for field in fields:
            if field in known_fields:
                ordered_dict[field] = default_dict[field]

        return ordered_dict
