#!/usr/bin/env python

import sys
try:
    import __builtin__
except ImportError:
    import builtins as __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 *
from gen_misc 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

    print("------------------------------------------------- Starting plug-"
          + "in -----------------------------------------------")

    print_timen("Running " + plug_in_name + "/" + cp_prefix + call_point + ".")
    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
        status_dir_path =\
            add_trailing_slash(os.environ.get("STATUS_DIR_PATH",
                                              os.environ['HOME']
                                              + "/status/"))
        if not os.path.isdir(status_dir_path):
            AUTOBOOT_EXECDIR = \
                add_trailing_slash(os.environ.get("AUTOBOOT_EXECDIR", ""))
            status_dir_path = AUTOBOOT_EXECDIR + "logs/"
            if not os.path.exists(status_dir_path):
                os.makedirs(status_dir_path)
        status_file_name = autoscript_prefix + "." + file_date_time_stamp() \
            + ".status"
        autoscript_subcmd = "autoscript --status_dir_path=" + status_dir_path\
            + " --status_file_name=" + status_file_name\
            + " --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
    print_issuing(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 + "/" + cp_prefix + call_point
    if shell_rc != 0:
        failed_plug_in_name = plug_in_name + "/" + cp_prefix + call_point
    if failed_plug_in_name != "" and autoscript and not stdout:
        shell_cmd("cat " + status_dir_path + status_file_name, quiet=1,
                  print_output=1)

    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:
        print_error("At least one plug-in failed.\n")
        return False


# Main

if not main():
    exit(1)
