#!/usr/bin/env python

import sys
import __builtin__
import subprocess
import os
import argparse

# python puts the program's directory path in sys.path[0].  In other words,
# the user ordinarily has no way to override python's choice of a module from
# its own dir.  We want to have that ability in our environment.  However, we
# don't want to break any established python modules that depend on this
# behavior.  So, we'll save the value from sys.path[0], delete it, import our
# modules and then restore sys.path to its original value.

save_path_0 = sys.path[0]
del sys.path[0]

from gen_print import *
from gen_valid import *
from gen_arg import *
from gen_plug_in import *
from gen_cmd import *

# Restore sys.path[0].
sys.path.insert(0, save_path_0)
# I use this variable in calls to print_var.
hex = 1

# Create parser object to process command line parameters and args.

# Create parser object.
parser = argparse.ArgumentParser(
    usage='%(prog)s [OPTIONS]',
    description="%(prog)s will process the plug-in packages passed to it." +
                "  A plug-in package is essentially a directory containing" +
                " one or more call point programs.  Each of these call point" +
                " programs must have a prefix of \"cp_\".  When calling" +
                " %(prog)s, a user must provide a call_point parameter" +
                " (described below).  For each plug-in package passed," +
                " %(prog)s will check for the presence of the specified call" +
                " point program in the plug-in directory.  If it is found," +
                " %(prog)s will run it.  It is the responsibility of the" +
                " caller to set any environment variables needed by the call" +
                " point programs.\n\nAfter each call point program" +
                " has been run, %(prog)s will print the following values in" +
                " the following formats for use by the calling program:\n" +
                "  failed_plug_in_name:               <failed plug-in value," +
                " if any>\n  shell_rc:                          " +
                "<shell return code value of last call point program - this" +
                " will be printed in hexadecimal format.  Also, be aware" +
                " that if a call point program returns a value it will be" +
                " shifted left 2 bytes (e.g. rc of 2 will be printed as" +
                " 0x00000200).  That is because the rightmost byte is" +
                " reserved for errors in calling the call point program" +
                " rather than errors generated by the call point program.>",
    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    prefix_chars='-+')

# Create arguments.
parser.add_argument(
    'plug_in_dir_paths',
    nargs='?',
    default="",
    help=plug_in_dir_paths_help_text + default_string)

parser.add_argument(
    '--call_point',
    default="setup",
    required=True,
    help='The call point program name.  This value must not include the' +
         ' "cp_" prefix.  For each plug-in package passed to this program,' +
         ' the specified call_point program will be called if it exists in' +
         ' the plug-in directory.' + default_string)

parser.add_argument(
    '--allow_shell_rc',
    default="0x00000000",
    help='The user may supply a value other than zero to indicate an' +
         ' acceptable non-zero return code.  For example, if this value' +
         ' equals 0x00000200, it means that for each plug-in call point that' +
         ' runs, a 0x00000200 will not be counted as a failure.  See note' +
         ' above regarding left-shifting of return codes.' + default_string)

parser.add_argument(
    '--stop_on_plug_in_failure',
    default=1,
    type=int,
    choices=[1, 0],
    help='If this parameter is set to 1, this program will stop and return ' +
         'non-zero if the call point program from any plug-in directory ' +
         'fails.  Conversely, if it is set to false, this program will run ' +
         'the call point program from each and every plug-in directory ' +
         'regardless of their return values.  Typical example cases where ' +
         'you\'d want to run all plug-in call points regardless of success ' +
         'or failure would be "cleanup" or "ffdc" call points.')

parser.add_argument(
    '--stop_on_non_zero_rc',
    default=0,
    type=int,
    choices=[1, 0],
    help='If this parm is set to 1 and a plug-in call point program returns ' +
         'a valid non-zero return code (see "allow_shell_rc" parm above),' +
         ' this program will stop processing and return 0 (success).  Since' +
         ' this constitutes a successful exit, this would normally be used' +
         ' where the caller wishes to stop processing if one of the plug-in' +
         ' directory call point programs returns a special value indicating' +
         ' that some special case has been found.  An example might be in' +
         ' calling some kind of "check_errl" call point program.  Such a' +
         ' call point program might return a 2 (i.e. 0x00000200) to indicate' +
         ' that a given error log entry was found in an "ignore" list and is' +
         ' therefore to be ignored.  That being the case, no other' +
         ' "check_errl" call point program would need to be called.' +
         default_string)

parser.add_argument(
    '--mch_class',
    default="obmc",
    help=mch_class_help_text + default_string)

# The stock_list will be passed to gen_get_options.  We populate it with the
# names of stock parm options we want.  These stock parms are pre-defined by
# gen_get_options.
stock_list = [("test_mode", 0), ("quiet", 1), ("debug", 0)]


def exit_function(signal_number=0,
                  frame=None):
    r"""
    Execute whenever the program ends normally or with the signals that we
    catch (i.e. TERM, INT).
    """

    dprint_executing()
    dprint_var(signal_number)

    qprint_pgm_footer()


def signal_handler(signal_number, frame):
    r"""
    Handle signals.  Without a function to catch a SIGTERM or SIGINT, our
    program would terminate immediately with return code 143 and without
    calling our exit_function.
    """

    # Our convention is to set up exit_function with atexit.registr() so
    # there is no need to explicitly call exit_function from here.

    dprint_executing()

    # Calling exit prevents us from returning to the code that was running
    # when we received the signal.
    exit(0)


def validate_parms():
    r"""
    Validate program parameters, etc.  Return True or False accordingly.
    """

    if not valid_value(call_point):
        return False

    global allow_shell_rc
    if not valid_integer(allow_shell_rc):
        return False

    # Convert to hex string for consistency in printout.
    allow_shell_rc = "0x%08x" % int(allow_shell_rc, 0)
    set_pgm_arg(allow_shell_rc)

    gen_post_validation(exit_function, signal_handler)

    return True


def run_pgm(plug_in_dir_path,
            call_point,
            allow_shell_rc):
    r"""
    Run the call point program in the given plug_in_dir_path.  Return the
    following:
    rc                              The return code - 0 = PASS, 1 = FAIL.
    shell_rc                        The shell return code returned by
                                    process_plug_in_packages.py.
    failed_plug_in_name             The failed plug in name (if any).

    Description of arguments:
    plug_in_dir_path                The directory path where the call_point
                                    program may be located.
    call_point                      The call point (e.g. "setup").  This
                                    program will look for a program named
                                    "cp_" + call_point in the
                                    plug_in_dir_path.  If no such call point
                                    program is found, this function returns an
                                    rc of 0 (i.e. success).
    allow_shell_rc                  The user may supply a value other than
                                    zero to indicate an acceptable non-zero
                                    return code.  For example, if this value
                                    equals 0x00000200, it means that for each
                                    plug-in call point that runs, a 0x00000200
                                    will not be counted as a failure.  See
                                    note above regarding left-shifting of
                                    return codes.
    """

    global autoscript

    rc = 0
    failed_plug_in_name = ""
    shell_rc = 0x00000000

    plug_in_name = os.path.basename(os.path.normpath(plug_in_dir_path))
    cp_prefix = "cp_"
    plug_in_pgm_path = plug_in_dir_path + cp_prefix + call_point
    if not os.path.exists(plug_in_pgm_path):
        # No such call point in this plug in dir path.  This is legal so we
        # return 0, etc.
        return rc, shell_rc, failed_plug_in_name

    # Get some stats on the file.
    cmd_buf = "stat -c '%n %s %z' " + plug_in_pgm_path
    dpissuing(cmd_buf)
    sub_proc = subprocess.Popen(cmd_buf, shell=True, stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT)
    out_buf, err_buf = sub_proc.communicate()
    shell_rc = sub_proc.returncode
    if shell_rc != 0:
        rc = 1
        print_var(shell_rc, hex)
        failed_plug_in_name = plug_in_name
        print(out_buf)
        print_var(failed_plug_in_name)
        print_var(shell_rc, hex)
        return rc, shell_rc, failed_plug_in_name

    print("------------------------------------------------- Starting plug-" +
          "in -----------------------------------------------")
    print(out_buf)
    if autoscript:
        stdout = 1 - quiet
        if AUTOBOOT_OPENBMC_NICKNAME != "":
            autoscript_prefix = AUTOBOOT_OPENBMC_NICKNAME + "."
        else:
            autoscript_prefix = ""
        autoscript_prefix += plug_in_name + ".cp_" + call_point
        autoscript_subcmd = "autoscript --quiet=1 --show_url=y --prefix=" +\
            autoscript_prefix + " --stdout=" + str(stdout) + " -- "
    else:
        autoscript_subcmd = ""

    cmd_buf = "PATH=" + plug_in_dir_path.rstrip("/") + ":${PATH} ; " +\
        autoscript_subcmd + cp_prefix + call_point
    pissuing(cmd_buf)

    sub_proc = subprocess.Popen(cmd_buf, shell=True)
    sub_proc.communicate()
    shell_rc = sub_proc.returncode
    # Shift to left.
    shell_rc *= 0x100
    if shell_rc != 0 and shell_rc != allow_shell_rc:
        rc = 1
        failed_plug_in_name = plug_in_name
    if shell_rc != 0:
        failed_plug_in_name = plug_in_name

    print("------------------------------------------------- Ending plug-in" +
          " -------------------------------------------------")
    if failed_plug_in_name != "":
        print_var(failed_plug_in_name)
    print_var(shell_rc, hex)

    return rc, shell_rc, failed_plug_in_name


def main():
    r"""
    This is the "main" function.  The advantage of having this function vs
    just doing this in the true mainline is that you can:
    - Declare local variables
    - Use "return" instead of "exit".
    - Indent 4 chars like you would in any function.
    This makes coding more consistent, i.e. it's easy to move code from here
    into a function and vice versa.
    """

    if not gen_get_options(parser, stock_list):
        return False

    if not validate_parms():
        return False

    qprint_pgm_header()

    # Access program parameter globals.
    global plug_in_dir_paths
    global mch_class
    global allow_shell_rc
    global stop_on_plug_in_failure
    global stop_on_non_zero_rc

    plug_in_packages_list = return_plug_in_packages_list(plug_in_dir_paths,
                                                         mch_class)

    qpvar(plug_in_packages_list)
    qprint("\n")

    allow_shell_rc = int(allow_shell_rc, 0)
    shell_rc = 0
    failed_plug_in_name = ""

    # If the autoscript program is present, we will use it to direct call point
    # program output to a separate status file.  This keeps the output of the
    # main program (i.e. OBMC Boot Test) cleaner and yet preserves call point
    # output if it is needed for debug.
    global autoscript
    global AUTOBOOT_OPENBMC_NICKNAME
    autoscript = 0
    AUTOBOOT_OPENBMC_NICKNAME = ""
    rc, out_buf = cmd_fnc("which autoscript", quiet=1, print_output=0,
                          show_err=0)
    if rc == 0:
        autoscript = 1
        AUTOBOOT_OPENBMC_NICKNAME = os.environ.get("AUTOBOOT_OPENBMC_NICKNAME",
                                                   "")
    ret_code = 0
    for plug_in_dir_path in plug_in_packages_list:
        rc, shell_rc, failed_plug_in_name = \
            run_pgm(plug_in_dir_path, call_point, allow_shell_rc)
        if rc != 0:
            ret_code = 1
            if stop_on_plug_in_failure:
                break
        if shell_rc != 0 and stop_on_non_zero_rc:
            qprint_time("Stopping on non-zero shell return code as requested" +
                        " by caller.\n")
            break

    if ret_code == 0:
        return True
    else:
        if not stop_on_plug_in_failure:
            # We print a summary error message to make the failure more
            # obvious.
            print_error("At least one plug-in failed.\n")
        return False


# Main

if not main():
    exit(1)
