#!/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_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 list(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.items():
        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.
        """

        gp.qprint(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.
        """

        gp.gp_print(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)
