#!/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 + ":${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

    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)
