#!/usr/bin/env python

r"""
This module has functions to support various data structures such as the
boot_table, valid_boot_list and boot_results_table.
"""

import os
import tempfile
import json
import glob
from tally_sheet import *

from robot.libraries.BuiltIn import BuiltIn
try:
    from robot.utils import DotDict
except ImportError:
    import collections

import gen_print as gp
import gen_robot_print as grp
import gen_valid as gv
import gen_misc as gm
import gen_cmd as gc
import var_funcs as vf

# The code base directory will be one level up from the directory containing
# this module.
code_base_dir_path = os.path.dirname(os.path.dirname(__file__)) + os.sep


def create_boot_table(file_path=None):

    r"""
    Read the boot table JSON file, convert it to an object and return it.

    Note that if the user is running without a global OS_HOST robot variable
    specified, this function will remove all of the "os_" start and end state
    requirements from the JSON data.

    Description of arguments:
    file_path  The path to the boot_table file.  If this value is not
               specified, it will be obtained from the "BOOT_TABLE_PATH"
               environment variable, if set.  Otherwise, it will default to
               "data/boot_table.json".  If this value is a relative path,
               this function will use the code_base_dir_path as the base
               directory (see definition above).
    """
    if file_path is None:
        file_path = os.environ.get('BOOT_TABLE_PATH', 'data/boot_table.json')

    if not file_path.startswith("/"):
        file_path = code_base_dir_path + file_path

    # Pre-process the file by removing blank lines and comment lines.
    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name

    cmd_buf = "egrep -v '^[ ]*$|^[ ]*#' " + file_path + " > " + temp_file_path
    gc.cmd_fnc_u(cmd_buf, quiet=1)

    boot_file = open(temp_file_path)
    boot_table = json.load(boot_file, object_hook=DotDict)

    # If the user is running without an OS_HOST, we remove os starting and
    # ending state requirements from the boot entries.
    os_host = BuiltIn().get_variable_value("${OS_HOST}", default="")
    if os_host == "":
        for boot in boot_table:
            state_keys = ['start', 'end']
            for state_key in state_keys:
                for sub_state in boot_table[boot][state_key]:
                    if sub_state.startswith("os_"):
                        boot_table[boot][state_key].pop(sub_state, None)

    # For every boot_type we should have a corresponding mfg mode boot type.
    enhanced_boot_table = DotDict()
    for key, value in boot_table.iteritems():
        enhanced_boot_table[key] = value
        enhanced_boot_table[key + " (mfg)"] = value

    return enhanced_boot_table


def create_valid_boot_list(boot_table):

    r"""
    Return a list of all of the valid boot types (e.g. ['BMC Power On',
    'BMC Power Off', ....]

    Description of arguments:
    boot_table  A boot table such as is returned by the create_boot_table
    function.
    """

    return list(boot_table.keys())


def read_boot_lists(dir_path="data/boot_lists/"):

    r"""
    Read the contents of all the boot lists files found in the given boot lists
    directory and return dictionary of the lists.

    Boot lists are simply files containing a boot test name on each line.
    These files are useful for categorizing and organizing boot tests.  For
    example, there may be a "Power_on" list, a "Power_off" list, etc.

    The names of the boot list files will be the keys to the top level
    dictionary.  Each dictionary entry is a list of all the boot tests found
    in the corresponding file.

    Here is an abbreviated look at the resulting boot_lists dictionary.

    boot_lists:
      boot_lists[All]:
        boot_lists[All][0]:                           BMC Power On
        boot_lists[All][1]:                           BMC Power Off
    ...
      boot_lists[Code_update]:
        boot_lists[Code_update][0]:                   BMC oob hpm
        boot_lists[Code_update][1]:                   BMC ib hpm
    ...

    Description of arguments:
    dir_path  The path to the directory containing the boot list files.  If
              this value is a relative path, this function will use the
              code_base_dir_path as the base directory (see definition above).
    """

    if not dir_path.startswith("/"):
        # Dir path is relative.
        dir_path = code_base_dir_path + dir_path

    # Get a list of all file names in the directory.
    boot_file_names = os.listdir(dir_path)

    boot_lists = DotDict()
    for boot_category in boot_file_names:
        file_path = gm.which(dir_path + boot_category)
        boot_list = gm.file_to_list(file_path, newlines=0, comments=0, trim=1)
        boot_lists[boot_category] = boot_list

    return boot_lists


def valid_boot_list(boot_list,
                    valid_boot_types):

    r"""
    Verify that each entry in boot_list is a supported boot test.

    Description of arguments:
    boot_list         An array (i.e. list) of boot test types
                      (e.g. "BMC Power On").
    valid_boot_types  A list of valid boot types such as that returned by
                      create_valid_boot_list.
    """

    for boot_name in boot_list:
        boot_name = boot_name.strip(" ")
        error_message = gv.svalid_value(boot_name,
                                        valid_values=valid_boot_types,
                                        var_name="boot_name")
        if error_message != "":
            BuiltIn().fail(gp.sprint_error(error_message))


class boot_results:

    r"""
    This class defines a boot_results table.
    """

    def __init__(self,
                 boot_table,
                 boot_pass=0,
                 boot_fail=0,
                 obj_name='boot_results'):

        r"""
        Initialize the boot results object.

        Description of arguments:
        boot_table  Boot table object (see definition above).  The boot table
                    contains all of the valid boot test types.  It can be
                    created with the create_boot_table function.
        boot_pass   An initial boot_pass value.  This program may be called
                    as part of a larger test suite.  As such there may already
                    have been some successful boot tests that we need to
                    keep track of.
        boot_fail   An initial boot_fail value.  This program may be called
                    as part of a larger test suite.  As such there may already
                    have been some unsuccessful boot tests that we need to
                    keep track of.
        obj_name    The name of this object.
        """

        # Store the method parms as class data.
        self.__obj_name = obj_name
        self.__initial_boot_pass = boot_pass
        self.__initial_boot_fail = boot_fail

        # Create boot_results_fields for use in creating boot_results table.
        boot_results_fields = DotDict([('total', 0), ('pass', 0), ('fail', 0)])
        # Create boot_results table.
        self.__boot_results = tally_sheet('boot type',
                                          boot_results_fields,
                                          'boot_test_results')
        self.__boot_results.set_sum_fields(['total', 'pass', 'fail'])
        self.__boot_results.set_calc_fields(['total=pass+fail'])
        # Create one row in the result table for each kind of boot test
        # in the boot_table (i.e. for all supported boot tests).
        for boot_name in list(boot_table.keys()):
            self.__boot_results.add_row(boot_name)

    def return_total_pass_fail(self):

        r"""
        Return the total boot_pass and boot_fail values.  This information is
        comprised of the pass/fail values from the table plus the initial
        pass/fail values.
        """

        totals_line = self.__boot_results.calc()
        return totals_line['pass'] + self.__initial_boot_pass,\
            totals_line['fail'] + self.__initial_boot_fail

    def update(self,
               boot_type,
               boot_status):

        r"""
        Update our boot_results_table.  This includes:
        - Updating the record for the given boot_type by incrementing the pass
          or fail field.
        - Calling the calc method to have the totals calculated.

        Description of arguments:
        boot_type    The type of boot test just done (e.g. "BMC Power On").
        boot_status  The status of the boot just done.  This should be equal to
                     either "pass" or "fail" (case-insensitive).
        """

        self.__boot_results.inc_row_field(boot_type, boot_status.lower())
        self.__boot_results.calc()

    def sprint_report(self,
                      header_footer="\n"):

        r"""
        String-print the formatted boot_resuls_table and return them.

        Description of arguments:
        header_footer  This indicates whether a header and footer are to be
                       included in the report.
        """

        buffer = ""

        buffer += gp.sprint(header_footer)
        buffer += self.__boot_results.sprint_report()
        buffer += gp.sprint(header_footer)

        return buffer

    def print_report(self,
                     header_footer="\n"):

        r"""
        Print the formatted boot_resuls_table to the console.

        See sprint_report for details.
        """

        grp.rqprint(self.sprint_report(header_footer))

    def sprint_obj(self):

        r"""
        sprint the fields of this object.  This would normally be for debug
        purposes only.
        """

        buffer = ""

        buffer += "class name: " + self.__class__.__name__ + "\n"
        buffer += gp.sprint_var(self.__obj_name)
        buffer += self.__boot_results.sprint_obj()
        buffer += gp.sprint_var(self.__initial_boot_pass)
        buffer += gp.sprint_var(self.__initial_boot_fail)

        return buffer

    def print_obj(self):

        r"""
        Print the fields of this object to stdout.  This would normally be for
        debug purposes.
        """

        grp.rprint(self.sprint_obj())


def create_boot_results_file_path(pgm_name,
                                  openbmc_nickname,
                                  master_pid):

    r"""
    Create a file path to be used to store a boot_results object.

    Description of argument(s):
    pgm_name          The name of the program.  This will form part of the
                      resulting file name.
    openbmc_nickname  The name of the system.  This could be a nickname, a
                      hostname, an IP, etc.  This will form part of the
                      resulting file name.
    master_pid        The master process id which will form part of the file
                      name.
    """

    USER = os.environ.get("USER", "")
    dir_path = "/tmp/" + USER + "/"
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)

    file_name_dict = vf.create_var_dict(pgm_name, openbmc_nickname, master_pid)
    return vf.create_file_path(file_name_dict, dir_path=dir_path,
                               file_suffix=":boot_results")


def cleanup_boot_results_file():

    r"""
    Delete all boot results files whose corresponding pids are no longer
    active.
    """

    # Use create_boot_results_file_path to create a globex to find all of the
    # existing boot results files.
    globex = create_boot_results_file_path("*", "*", "*")
    file_list = sorted(glob.glob(globex))
    for file_path in file_list:
        # Use parse_file_path to extract info from the file path.
        file_dict = vf.parse_file_path(file_path)
        if gm.pid_active(file_dict['master_pid']):
            gp.qprint_timen("Preserving " + file_path + ".")
        else:
            gc.cmd_fnc("rm -f " + file_path)

