#!/usr/bin/env python

r"""
This module provides functions which are useful to plug-in call point programs.
"""

import sys
import os
import re
import collections

import gen_print as gp
import gen_misc as gm
import gen_cmd as gc

PLUG_VAR_PREFIX = os.environ.get("PLUG_VAR_PREFIX", "AUTOBOOT")


def get_plug_in_package_name(case=None):
    r"""
    Return the plug-in package name (e.g. "OS_Console", "DB_Logging").

    Description of argument(s):
    case                            Indicates whether the value returned should be converted to upper or
                                    lower case.  Valid values are "upper", "lower" or None.
    """

    plug_in_package_name = os.path.basename(gp.pgm_dir_path[:-1])
    if case == "upper":
        return plug_in_package_name.upper()
    elif case == "lower":
        return plug_in_package_name.lower()
    else:
        return plug_in_package_name


def return_plug_vars(general=True,
                     custom=True):
    r"""
    Return an OrderedDict which is sorted by key and which contains all of the plug-in environment variables.

    Example excerpt of resulting dictionary:

    plug_var_dict:
      [AUTOBOOT_BASE_TOOL_DIR_PATH]:  /tmp/
      [AUTOBOOT_BB_LEVEL]:            <blank>
      [AUTOBOOT_BOOT_FAIL]:           0
      ...

    This function also does the following:
    - Set a default value for environment variable AUTOBOOT_OPENBMC_NICKNAME/AUTOIPL_FSP1_NICKNAME if it is
      not already set.
    - Register PASSWORD variables to prevent their values from being printed.

    Note: The programmer may set a default for any given environment variable by declaring a global variable
    of the same name and setting its value.  For example, let's say the calling program has this global
    declaration:

    PERF_EXERCISERS_TOTAL_TIMEOUT = '180'

    If environment variable PERF_EXERCISERS_TOTAL_TIMEOUT is blank or not set, this function will set it to
    '180'.

    Furthermore, if such a default variable declaration is not a string, this function will preserve that
    non-string type in setting global variables (with the exception of os.environ values which must be
    string).  Example:

    NVDIMM_ENCRYPT = 0

    Description of argument(s):
    general                         Return general plug-in parms (e.g. those beginning with "AUTOBOOT" or
                                    "AUTOGUI").
    custom                          Return custom plug-in parms (i.e. those beginning with the upper case
                                    name of the plug-in package, for example "OBMC_SAMPLE_PARM1").
    """

    regex_list = []
    if not (general or custom):
        return collections.OrderedDict()
    plug_in_package_name = get_plug_in_package_name(case="upper")
    if general:
        regex_list = [PLUG_VAR_PREFIX, "AUTOGUI"]
    if custom:
        regex_list.append(plug_in_package_name)

    regex = "^(" + "|".join(regex_list) + ")_"

    # Set a default for nickname.
    if os.environ.get("AUTOBOOT_OPENBMC_NICKNAME", "") == "":
        os.environ['AUTOBOOT_OPENBMC_NICKNAME'] = \
            os.environ.get("AUTOBOOT_OPENBMC_HOST", "")

    if os.environ.get("AUTOIPL_FSP1_NICKNAME", "") == "":
        os.environ['AUTOIPL_FSP1_NICKNAME'] = \
            os.environ.get("AUTOIPL_FSP1_NAME", "").split(".")[0]

    # For all variables specified in the parm_def file, we want them to default to "" rather than being unset.
    # Process the parm_def file if it exists.
    parm_def_file_path = gp.pgm_dir_path + "parm_def"
    if os.path.exists(parm_def_file_path):
        parm_defs = gm.my_parm_file(parm_def_file_path)
    else:
        parm_defs = collections.OrderedDict()
    # Example parm_defs:
    # parm_defs:
    #   parm_defs[rest_fail]:           boolean
    #   parm_defs[command]:             string
    #   parm_defs[esel_stop_file_path]: string

    # Create a list of plug-in environment variables by pre-pending <all caps plug-in package name>_<all
    # caps var name>
    plug_in_parm_names = [plug_in_package_name + "_" + x for x in
                          map(str.upper, parm_defs.keys())]
    # Example plug_in_parm_names:
    # plug_in_parm_names:
    #  plug_in_parm_names[0]: STOP_REST_FAIL
    #  plug_in_parm_names[1]: STOP_COMMAND
    #  plug_in_parm_names[2]: STOP_ESEL_STOP_FILE_PATH

    # os.environ only accepts string values.  However, if the user defines default values of other types
    # (e.g. int), we wish to preserve the type.
    non_string_defaults = {}
    # Initialize unset plug-in vars.
    for var_name in plug_in_parm_names:
        # If there is a global variable with the same name as the environment variable, use its value as a
        # default.
        default_value = gm.get_mod_global(var_name, "")
        if type(default_value) is not str:
            non_string_defaults[var_name] = type(default_value)
        os.environ[var_name] = os.environ.get(var_name, str(default_value))
        if os.environ[var_name] == "":
            os.environ[var_name] = default_value

    plug_var_dict = \
        collections.OrderedDict(sorted({k: v for (k, v) in
                                        os.environ.items()
                                        if re.match(regex, k)}.items()))
    # Restore the types of any variables where the caller had defined default values.
    for key, value in non_string_defaults.items():
        cmd_buf = "plug_var_dict[key] = " + str(value).split("'")[1] + "(plug_var_dict[key]"
        if value is int:
            # Use int base argument of 0 to allow it to interpret hex strings.
            cmd_buf += ", 0)"
        else:
            cmd_buf += ")"
        exec(cmd_buf)
    # Register password values to prevent printing them out.  Any plug var whose name ends in PASSWORD will
    # be registered.
    password_vals = {k: v for (k, v) in plug_var_dict.items()
                     if re.match(r".*_PASSWORD$", k)}.values()
    map(gp.register_passwords, password_vals)

    return plug_var_dict


def sprint_plug_vars(headers=1, **kwargs):
    r"""
    Sprint the plug-in environment variables (i.e. those that begin with the global PLUG_VAR_PREFIX value or
    those that begin with <plug-in package_name>_ in upper case letters.).

    Example excerpt of output:
    AUTOBOOT_BASE_TOOL_DIR_PATH=/tmp/
    AUTOBOOT_BB_LEVEL=
    AUTOBOOT_BOOT_FAIL=0
    AUTOBOOT_BOOT_FAIL_THRESHOLD=1000000

    Description of argument(s):
    headers                         Print a header and a footer.
    kwargs                          These are passed directly to return_plug_vars.  See return_plug_vars doc
                                    string for details.
    """
    plug_var_dict = return_plug_vars(**kwargs)
    buffer = ""
    if headers:
        buffer += "\n" + gp.sprint_dashes()
    for key, value in plug_var_dict.items():
        buffer += gp.sprint_varx(key, value)
    if headers:
        buffer += gp.sprint_dashes() + "\n"

    return buffer


def print_plug_in_header():
    r"""
    Print plug-in header.

    When debug is set, print all plug_prefix variables (e.g. AUTOBOOT_OPENBMC_HOST, etc.) and all plug-in
    environment variables (e.g. OBMC_SAMPLE_PARM1) with surrounding dashed lines.  When debug is not set,
    print only the plug-in environment variables (e.g. OBMC_SAMPLE_PARM1) with no surrounding dashed lines.

    NOTE: plug-in environment variables means any variable defined in the <plug-in dir>/parm_def file plus
    any environment variables whose names begin with the upper-case plug-in package name.
    """

    dprint_plug_vars()
    if not debug:
        qprint_plug_vars(headers=0, general=False, custom=True)


def get_plug_vars(mod_name="__main__"):
    r"""
    Get all plug-in variables and put them in corresponding global variables.

    This would include all environment variables beginning with either the global PLUG_VAR_PREFIX value or
    with the upper case version of the plug-in package name + underscore (e.g. OP_SAMPLE_VAR1 for plug-in
    OP_Sample).

    The global variables to be set will be both with and without the global PLUG_VAR_PREFIX value prefix.
    For example, if the environment variable in question is AUTOBOOT_OPENBMC_HOST, this function will set
    global variable AUTOBOOT_OPENBMC_HOST and global variable OPENBMC_HOST.

    Description of argument(s):
    mod_name                        The name of the module whose global plug-in variables should be retrieved.
    """

    module = sys.modules[mod_name]
    plug_var_dict = return_plug_vars()

    # Get all PLUG_VAR_PREFIX environment variables and put them into globals.
    for key, value in plug_var_dict.items():
        setattr(module, key, value)
        setattr(module, re.sub("^" + PLUG_VAR_PREFIX + "_", "", key), value)


def get_plug_default(var_name,
                     default=None):
    r"""
    Derive and return a default value for the given parm variable.

    Dependencies:
    Global variable PLUG_VAR_PREFIX must be set.

    This function will assign a default by checking the following environment variables in the order shown.
    The first one that has a value will be used.
    - <upper case package_name>_<var_name>
    - <PLUG_VAR_PREFIX>_OVERRIDE_<var_name>
    - <PLUG_VAR_PREFIX>_<var_name>

    If none of these are found, this function will return the value passed by the caller in the "default"
    parm.

    Example:

    Let's say your plug-in is named "OS_Console" and you call this function as follows:

    get_plug_default("quiet", 0)

    The first of these environment variables that is found to be set will be used to provide the default
    value.
    - OS_CONSOLE_QUIET
    - AUTOBOOT_OVERRIDE_QUIET
    - AUTOBOOT_QUIET

    If none of those has a value, 0 (as specified by the caller in this example) is returned.

    Let's say the master driver program is named obmc_boot.  obmc_boot program is responsible for calling
    plug-ins.  Let's further suppose that the user wishes to run the master program with --debug=0 but wishes
    to have all plug-ins run with --debug=1.  This could be accomplished with the following call:
    export AUTOBOOT_OVERRIDE_DEBUG=1 ; obmc_boot --debug=0 --plug_in_dir_paths=<list of plug ins>

    As another example, let's suppose that the user wishes to have just the OS_Console plug-in run with debug
    and everything else to default to debug=0.  This could be accomplished as follows:
    export OS_CONSOLE_DEBUG=1 ; obmc_boot --debug=0 --plug_in_dir_paths=<list of plug ins>

    And as one more example, let's say the user wishes to have obmc_boot and OS_Console run without debug but
    have all other plug-ins run with debug:
    export AUTOBOOT_OVERRIDE_DEBUG=1 ; export OS_CONSOLE_DEBUG=0 ; obmc_boot --debug=0
    --plug_in_dir_paths=<list of plug ins>

    Description of argument(s):
    var_name                        The name of the variable for which a default value is to be calculated.
    default                         The default value if one cannot be determined.
    """

    var_name = var_name.upper()
    plug_in_package_name = get_plug_in_package_name(case="upper")

    package_var_name = plug_in_package_name + "_" + var_name
    default_value = os.environ.get(package_var_name, None)
    if default_value is not None:
        # A package-name version of the variable was found so return its value.
        return(default_value)

    plug_var_name = PLUG_VAR_PREFIX + "_OVERRIDE_" + var_name
    default_value = os.environ.get(plug_var_name, None)
    if default_value is not None:
        # A PLUG_VAR_PREFIX version of the variable was found so return its value.
        return default_value

    plug_var_name = PLUG_VAR_PREFIX + "_" + var_name
    default_value = os.environ.get(plug_var_name, None)
    if default_value is not None:
        # A PLUG_VAR_PREFIX version of the variable was found so return its value.
        return default_value

    return default


def srequired_plug_in(req_plug_in_names,
                      plug_in_dir_paths=None):
    r"""
    Return an empty string if the required plug-ins are found in plug_in_dir_paths.  Otherwise, return an
    error string.

    Example call:
    error_message = srequired_plug_in(req_plug_in_names, plug_in_dir_paths)

    Description of argument(s):
    req_plug_in_names               A list of plug_in names that the caller requires (e.g. ['OS_Console']).
    plug_in_dir_paths               A string which is a colon-delimited list of plug-ins specified by the
                                    user (e.g. DB_Logging:FFDC:OS_Console:Perf).  Path values (e.g.
                                    "/home/robot/dir1") will be stripped from this list to do the analysis.
                                    Default value is the <PLUG_VAR_PREFIX>_PLUG_IN_DIR_PATHS environment
                                    variable.
    """

    # Calculate default value for plug_in_dir_paths.
    if plug_in_dir_paths is None:
        plug_in_dir_paths = os.environ.get(PLUG_VAR_PREFIX
                                           + "_PLUG_IN_DIR_PATHS", "")

    error_message = ""

    # Convert plug_in_dir_paths to a list of base names.
    plug_in_dir_paths = \
        list(filter(None, map(os.path.basename, plug_in_dir_paths.split(":"))))

    # Check for each of the user's required plug-ins.
    for plug_in_name in req_plug_in_names:
        if plug_in_name not in plug_in_dir_paths:
            error_message = "The \"" + get_plug_in_package_name() +\
                "\" plug-in cannot run unless the user also selects the \"" +\
                plug_in_name + "\" plug in:\n" +\
                gp.sprint_var(plug_in_dir_paths)

    return error_message


def required_plug_in(req_plug_in_names,
                     plug_in_dir_paths=None):
    r"""
    Return True if each of the plug-ins in req_plug_in_names can be found in plug_in_dir_paths  Otherwise,
    return False and print an error message to stderr.

    Example call:
    if not required_plug_in(['OS_Console'], AUTOBOOT_PLUG_IN_DIR_PATHS):
        return False

    Description of argument(s):
    (See Description of arguments for srequired_plug_in (above)).
    """

    error_message = srequired_plug_in(req_plug_in_names, plug_in_dir_paths)
    if not error_message == "":
        gp.print_error_report(error_message)
        return False

    return True


def compose_plug_in_save_dir_path(plug_in_package_name=None):
    r"""
    Create and return a directory path name that is suitable for saving plug-in data.

    The name will be comprised of things such as plug_in package name, pid, etc. in order to guarantee that
    it is unique for a given test run.

    Description of argument(s):
    plug_in_package_name            The plug-in package name.  This defaults to the name of the caller's
                                    plug-in package.  However, the caller can specify another value in order
                                    to retrieve data saved by another plug-in package.
    """

    plug_in_package_name = gm.dft(plug_in_package_name,
                                  get_plug_in_package_name())

    BASE_TOOL_DIR_PATH = \
        gm.add_trailing_slash(os.environ.get(PLUG_VAR_PREFIX
                                             + "_BASE_TOOL_DIR_PATH",
                                             "/tmp/"))
    NICKNAME = os.environ.get("AUTOBOOT_OPENBMC_NICKNAME", "")
    if NICKNAME == "":
        NICKNAME = os.environ["AUTOIPL_FSP1_NICKNAME"]
    MASTER_PID = os.environ[PLUG_VAR_PREFIX + "_MASTER_PID"]
    gp.qprint_vars(BASE_TOOL_DIR_PATH, NICKNAME, plug_in_package_name,
                   MASTER_PID)
    return BASE_TOOL_DIR_PATH + gm.username() + "/" + NICKNAME + "/" +\
        plug_in_package_name + "/" + str(MASTER_PID) + "/"


def create_plug_in_save_dir(plug_in_package_name=None):
    r"""
    Create a directory suitable for saving plug-in processing data and return its path name.

    See compose_plug_in_save_dir_path for details.

    Description of argument(s):
    plug_in_package_name            See compose_plug_in_save_dir_path for details.
    """

    plug_in_save_dir_path = compose_plug_in_save_dir_path(plug_in_package_name)
    if os.path.isdir(plug_in_save_dir_path):
        return plug_in_save_dir_path
    gc.shell_cmd("mkdir -p " + plug_in_save_dir_path)
    return plug_in_save_dir_path


def delete_plug_in_save_dir(plug_in_package_name=None):
    r"""
    Delete the plug_in save directory.  See compose_plug_in_save_dir_path for details.

    Description of argument(s):
    plug_in_package_name            See compose_plug_in_save_dir_path for details.
    """

    gc.shell_cmd("rm -rf "
                 + compose_plug_in_save_dir_path(plug_in_package_name))


def save_plug_in_value(value, plug_in_package_name=None):
    r"""
    Save a value in a plug-in save file.  The value may be retrieved later via a call to the
    restore_plug_in_value function.

    This function will figure out the variable name of the value passed and use that name in creating the
    plug-in save file.

    Example call:

    my_var1 = 5
    save_plug_in_value(my_var1)

    In this example, the value "5" would be saved to the "my_var1" file in the plug-in save directory.

    Description of argument(s):
    value                           The value to be saved.
    plug_in_package_name            See compose_plug_in_save_dir_path for details.
    """

    # Get the name of the variable used as argument one to this function.
    var_name = gp.get_arg_name(0, 1, stack_frame_ix=2)
    plug_in_save_dir_path = create_plug_in_save_dir(plug_in_package_name)
    save_file_path = plug_in_save_dir_path + var_name
    gp.qprint_timen("Saving \"" + var_name + "\" value.")
    gc.shell_cmd("echo '" + str(value) + "' > " + save_file_path)


def restore_plug_in_value(default="", plug_in_package_name=None):
    r"""
    Return a value from a plug-in save file.

    The name of the value to be restored will be determined by this function based on the lvalue being
    assigned.  Consider the following example:

    my_var1 = restore_plug_in_value(2)

    In this example, this function would look for the "my_var1" file in the plug-in save directory, read its
    value and return it.  If no such file exists, the default value of 2 would be returned.

    Description of argument(s):
    default                         The default value to be returned if there is no plug-in save file for the
                                    value in question.
    plug_in_package_name            See compose_plug_in_save_dir_path for details.
    """

    # Get the lvalue from the caller's invocation of this function.
    lvalue = gp.get_arg_name(0, -1, stack_frame_ix=2)
    plug_in_save_dir_path = create_plug_in_save_dir(plug_in_package_name)
    save_file_path = plug_in_save_dir_path + lvalue
    if os.path.isfile(save_file_path):
        gp.qprint_timen("Restoring " + lvalue + " value from "
                        + save_file_path + ".")
        value = gm.file_to_list(save_file_path, newlines=0, comments=0,
                                trim=1)[0]
        if type(default) is bool:
            # Convert from string to bool.
            value = (value == 'True')
        if type(default) is int:
            # Convert from string to int.
            value = int(value)
        gp.qprint_varx(lvalue, value)
        return value
    else:
        gp.qprint_timen("Save file " + save_file_path
                        + " does not exist so returning default value.")
        gp.qprint_var(default)
        return default


def exit_not_master():
    r"""
    Exit the program with return code zero if this program was NOT called by the master program.

    There are cases where plug-ins are called by a multi-layered stack:

    master_wrapper
        obmc_boot_test.py
            Example_plug_in/cp_setup

    In a scenario like this, Example_plug_in/cp_setup may be called once directly by master_wrapper (the
    master) and and then called again directly by obmc_boot_test.py (the child).  Some plug-in programs may
    wish to avoid doing any processing on the second such call.  This function will achieve that purpose.

    This function will print a standard message to stdout prior to exiting.
    """

    AUTOBOOT_MASTER_PID = gm.get_mod_global("AUTOBOOT_MASTER_PID")
    AUTOBOOT_PROGRAM_PID = gm.get_mod_global("AUTOBOOT_PROGRAM_PID")

    if AUTOBOOT_MASTER_PID != AUTOBOOT_PROGRAM_PID:
        message = get_plug_in_package_name() + "/" + gp.pgm_name + " is not" \
            + " being called by the master program in the stack so no action" \
            + " will be taken."
        gp.qprint_timen(message)
        gp.qprint_vars(AUTOBOOT_MASTER_PID, AUTOBOOT_PROGRAM_PID)
        exit(0)


def stop_test_rc():
    r"""
    Return the constant stop test return code value.

    When a plug-in call point program returns this value, it indicates that master program should stop
    running.
    """

    return 0x00000002


# Create print wrapper functions for all sprint functions defined above.
# func_names contains a list of all print functions which should be created from their sprint counterparts.
func_names = ['print_plug_vars']

# stderr_func_names is a list of functions whose output should go to stderr rather than stdout.
stderr_func_names = []

replace_dict = dict(gp.replace_dict)
replace_dict['mod_qualifier'] = 'gp.'
func_defs = gp.create_print_wrapper_funcs(func_names, stderr_func_names,
                                          replace_dict)
gp.gp_debug_print(func_defs)
exec(func_defs)
