#!/usr/bin/env python3

r"""
Define the tally_sheet class.
"""

import sys
import collections
import copy
import re

try:
    from robot.utils import DotDict
except ImportError:
    pass

import gen_print as gp


class tally_sheet:

    r"""
    This class is the implementation of a tally sheet.  The sheet can be viewed as rows and columns.  Each
    row has a unique key field.

    This class provides methods to tally the results (totals, etc.).

    Example code:

    # Create an ordered dict to represent your field names/initial values.
    try:
        boot_results_fields = collections.OrderedDict([('total', 0), ('pass', 0), ('fail', 0)])
    except AttributeError:
        boot_results_fields = DotDict([('total', 0), ('pass', 0), ('fail', 0)])
    # Create the tally sheet.
    boot_test_results = tally_sheet('boot type', boot_results_fields, 'boot_test_results')
    # Set your sum fields (fields which are to be totalled).
    boot_test_results.set_sum_fields(['total', 'pass', 'fail'])
    # Set calc fields (within a row, a certain field can be derived from other fields in the row.
    boot_test_results.set_calc_fields(['total=pass+fail'])

    # Create some records.
    boot_test_results.add_row('BMC Power On')
    boot_test_results.add_row('BMC Power Off')

    # Increment field values.
    boot_test_results.inc_row_field('BMC Power On', 'pass')
    boot_test_results.inc_row_field('BMC Power Off', 'pass')
    boot_test_results.inc_row_field('BMC Power On', 'fail')
    # Have the results tallied...
    boot_test_results.calc()
    # And printed...
    boot_test_results.print_report()

    Example result:

    Boot Type                           Total Pass Fail
    ----------------------------------- ----- ---- ----
    BMC Power On                            2    1    1
    BMC Power Off                           1    1    0
    ===================================================
    Totals                          3    2    1

    """

    def __init__(self,
                 row_key_field_name='Description',
                 init_fields_dict=dict(),
                 obj_name='tally_sheet'):
        r"""
        Create a tally sheet object.

        Description of arguments:
        row_key_field_name          The name of the row key field (e.g. boot_type, team_name, etc.)
        init_fields_dict            A dictionary which contains field names/initial values.
        obj_name                    The name of the tally sheet.
        """

        self.__obj_name = obj_name
        # The row key field uniquely identifies the row.
        self.__row_key_field_name = row_key_field_name
        # Create a "table" which is an ordered dictionary.
        # If we're running python 2.7 or later, collections has an OrderedDict we can use.  Otherwise, we'll
        # try to use the DotDict (a robot library).  If neither of those are available, we fail.
        try:
            self.__table = collections.OrderedDict()
        except AttributeError:
            self.__table = DotDict()
        # Save the initial fields dictionary.
        self.__init_fields_dict = init_fields_dict
        self.__totals_line = init_fields_dict
        self.__sum_fields = []
        self.__calc_fields = []

    def init(self,
             row_key_field_name,
             init_fields_dict,
             obj_name='tally_sheet'):
        self.__init__(row_key_field_name,
                      init_fields_dict,
                      obj_name='tally_sheet')

    def set_sum_fields(self, sum_fields):
        r"""
        Set the sum fields, i.e. create a list of field names which are to be summed and included on the
        totals line of reports.

        Description of arguments:
        sum_fields                  A list of field names.
        """

        self.__sum_fields = sum_fields

    def set_calc_fields(self, calc_fields):
        r"""
        Set the calc fields, i.e. create a list of field names within a given row which are to be calculated
        for the user.

        Description of arguments:
        calc_fields                 A string expression such as 'total=pass+fail' which shows which field on
                                    a given row is derived from other fields in the same row.
        """

        self.__calc_fields = calc_fields

    def add_row(self, row_key, init_fields_dict=None):
        r"""
        Add a row to the tally sheet.

        Description of arguments:
        row_key                     A unique key value.
        init_fields_dict            A dictionary of field names/initial values.  The number of fields in this
                                    dictionary must be the same as what was specified when the tally sheet
                                    was created.  If no value is passed, the value used to create the tally
                                    sheet will be used.
        """

        if row_key in self.__table:
            # If we allow this, the row values get re-initialized.
            message = "An entry for \"" + row_key + "\" already exists in"
            message += " tally sheet."
            raise ValueError(message)
        if init_fields_dict is None:
            init_fields_dict = self.__init_fields_dict
        try:
            self.__table[row_key] = collections.OrderedDict(init_fields_dict)
        except AttributeError:
            self.__table[row_key] = DotDict(init_fields_dict)

    def update_row_field(self, row_key, field_key, value):
        r"""
        Update a field in a row with the specified value.

        Description of arguments:
        row_key                     A unique key value that identifies the row to be updated.
        field_key                   The key that identifies which field in the row that is to be updated.
        value                       The value to set into the specified row/field.
        """

        self.__table[row_key][field_key] = value

    def inc_row_field(self, row_key, field_key):
        r"""
        Increment the value of the specified field in the specified row.  The value of the field must be
        numeric.

        Description of arguments:
        row_key                     A unique key value that identifies the row to be updated.
        field_key                   The key that identifies which field in the row that is to be updated.
        """

        self.__table[row_key][field_key] += 1

    def dec_row_field(self, row_key, field_key):
        r"""
        Decrement the value of the specified field in the specified row.  The value of the field must be
        numeric.

        Description of arguments:
        row_key                     A unique key value that identifies the row to be updated.
        field_key                   The key that identifies which field in the row that is to be updated.
        """

        self.__table[row_key][field_key] -= 1

    def calc(self):
        r"""
        Calculate totals and row calc fields.  Also, return totals_line dictionary.
        """

        self.__totals_line = copy.deepcopy(self.__init_fields_dict)
        # Walk through the rows of the table.
        for row_key, value in self.__table.items():
            # Walk through the calc fields and process them.
            for calc_field in self.__calc_fields:
                tokens = [i for i in re.split(r'(\d+|\W+)', calc_field) if i]
                cmd_buf = ""
                for token in tokens:
                    if token in ("=", "+", "-", "*", "/"):
                        cmd_buf += token + " "
                    else:
                        # Note: Using "mangled" name for the sake of the exec
                        # statement (below).
                        cmd_buf += "self._" + self.__class__.__name__ +\
                                   "__table['" + row_key + "']['" +\
                                   token + "'] "
                exec(cmd_buf)

            for field_key, sub_value in value.items():
                if field_key in self.__sum_fields:
                    self.__totals_line[field_key] += sub_value

        return self.__totals_line

    def sprint_obj(self):
        r"""
        sprint the fields of this object.  This would normally be for debug purposes.
        """

        buffer = ""

        buffer += "class name: " + self.__class__.__name__ + "\n"
        buffer += gp.sprint_var(self.__obj_name)
        buffer += gp.sprint_var(self.__row_key_field_name)
        buffer += gp.sprint_var(self.__table)
        buffer += gp.sprint_var(self.__init_fields_dict)
        buffer += gp.sprint_var(self.__sum_fields)
        buffer += gp.sprint_var(self.__totals_line)
        buffer += gp.sprint_var(self.__calc_fields)
        buffer += gp.sprint_var(self.__table)

        return buffer

    def print_obj(self):
        r"""
        print the fields of this object to stdout.  This would normally be for debug purposes.
        """

        sys.stdout.write(self.sprint_obj())

    def sprint_report(self):
        r"""
        sprint the tally sheet in a formatted way.
        """

        buffer = ""
        # Build format strings.
        col_names = [self.__row_key_field_name.title()]
        report_width = 40
        key_width = 40
        format_string = '{0:<' + str(key_width) + '}'
        dash_format_string = '{0:-<' + str(key_width) + '}'
        field_num = 0

        try:
            first_rec = next(iter(self.__table.items()))
            for row_key, value in first_rec[1].items():
                field_num += 1
                if isinstance(value, int):
                    align = ':>'
                else:
                    align = ':<'
                format_string += ' {' + str(field_num) + align +\
                                 str(len(row_key)) + '}'
                dash_format_string += ' {' + str(field_num) + ':->' +\
                                      str(len(row_key)) + '}'
                report_width += 1 + len(row_key)
                col_names.append(row_key.title())
        except StopIteration:
            pass
        num_fields = field_num + 1
        totals_line_fmt = '{0:=<' + str(report_width) + '}'

        buffer += format_string.format(*col_names) + "\n"
        buffer += dash_format_string.format(*([''] * num_fields)) + "\n"
        for row_key, value in self.__table.items():
            buffer += format_string.format(row_key, *value.values()) + "\n"

        buffer += totals_line_fmt.format('') + "\n"
        buffer += format_string.format('Totals',
                                       *self.__totals_line.values()) + "\n"

        return buffer

    def print_report(self):
        r"""
        print the tally sheet in a formatted way.
        """

        sys.stdout.write(self.sprint_report())
