#!/usr/bin/env python

r"""
Check for stop conditions.  Return code of 2 if stop conditions are found.
"""

import sys
import subprocess

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

from gen_print import *
from gen_valid import *
from gen_arg import *
from gen_misc import *
from gen_cmd import *
from gen_plug_in_utils import *
from gen_call_robot import *

# Restore sys.path[0].
sys.path.insert(0, save_path_0)

# Set exit_on_error for gen_valid functions.
set_exit_on_error(True)

# Initialize.
STOP_REST_FAIL = ''
STOP_COMMAND = ''
stop_test_rc = 2

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

# Create parser object.
parser = argparse.ArgumentParser(
    usage='%(prog)s [OPTIONS]',
    description="If the \"Stop\" plug-in is selected by the user, %(prog)s" +
    " is called by OBMC Boot Test after each boot test.  If %(prog)s returns" +
    " " + str(stop_test_rc) + ", then OBMC Boot Test will stop.  The user" +
    " may set environment variable STOP_COMMAND to contain any valid bash" +
    " command or program.  %(prog)s will run this stop command.  If the stop" +
    " command returns non-zero, then %(prog)s will return " +
    str(stop_test_rc) + ".  %(prog)s recognizes some special values for" +
    " STOP_COMMAND: 1) \"FAIL\" means that OBMC Boot Test should stop" +
    " whenever a boot test fails. 2) \"ALL\" means that OBMC Boot Test" +
    " should stop after any boot test.  If environment variable" +
    " STOP_REST_FAIL is set, OBMC Boot Test will stop if REST commands are" +
    " no longer working.",
    formatter_class=argparse.RawTextHelpFormatter,
    prefix_chars='-+')

# 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", get_plug_default("quiet", 0)),
              ("debug", get_plug_default("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)

    process_robot_output_files()

    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.register() 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 (i.e. pass/fail)
    accordingly.
    """

    get_plug_vars()

    valid_value(AUTOBOOT_OPENBMC_HOST)

    gen_post_validation(exit_function, signal_handler)

    return True


def stop_check():
    r"""
    Stop this program with the stop check return code.
    """

    if MASTER_PID != PROGRAM_PID:
        stop_check_rc = stop_test_rc
        save_plug_in_value(stop_check_rc)
    exit(stop_test_rc)


def rest_fail():
    r"""
    If STOP_REST_FAIL, then this function will determine whether REST commands
    to the target are working.  If not, this function will stop the program by
    returning stop_test_rc.
    """

    if STOP_REST_FAIL != '1':
        return

    print_timen("Checking to see whether REST commands are working.")
    init_robot_out_parms(get_plug_in_package_name() + "." + pgm_name + ".")
    lib_file_path = init_robot_file_path("lib/state.py") + ":"\
        + init_robot_file_path("lib/gen_robot_print.py")
    set_mod_global(lib_file_path)
    timeout = '0 seconds'
    interval = '1 second'
    keyword_string = "${match_state}=  Create Dictionary  rest=1 ;" +\
        " ${state}=  Wait State  ${match_state}  " + timeout + "  " +\
        interval + "  quiet=${1} ; Rpvar  state"
    set_mod_global(keyword_string)

    cmd_buf = create_robot_cmd_string("extended/run_keyword.robot",
                                      OPENBMC_HOST, REST_USERNAME,
                                      REST_PASSWORD, keyword_string,
                                      lib_file_path, quiet, test_mode, debug,
                                      outputdir, output, log, report, loglevel)
    if not robot_cmd_fnc(cmd_buf):
        print_timen("The caller wishes to stop test execution if REST" +
                    " commands are failing.")
        stop_check()
    print_timen("REST commands are working so no reason as of yet to stop" +
                " the test.")


def esel_stop_check():
    r"""
    Run the esel_stop_check program to determine whether any eSEL entries
    found warrant stopping the test run.  See esel_stop_check help text for
    details.
    """

    if STOP_ESEL_STOP_FILE_PATH == "":
        return

    cmd_buf = "esel_stop_check --esel_stop_file_path=" +\
        STOP_ESEL_STOP_FILE_PATH
    shell_rc, out_buf = cmd_fnc_u(cmd_buf, show_err=0)
    if shell_rc == stop_test_rc:
        print_timen("The caller wishes to stop test execution based on the" +
                    " presence of certain esel entries.")
        stop_check()


def main():

    if not gen_get_options(parser, stock_list):
        return False

    if not validate_parms():
        return False

    qprint_pgm_header()

    if not debug:
        qprint_vars(STOP_REST_FAIL, STOP_COMMAND, AUTOBOOT_BOOT_SUCCESS)

    print_plug_in_header()

    if STOP_COMMAND.upper() == "FAIL":
        if AUTOBOOT_BOOT_SUCCESS == "0":
            print_timen("The caller wishes to stop after each boot failure.")
            stop_check()
    elif STOP_COMMAND.upper() == "ALL":
        print_timen("The caller wishes to stop after each boot test.")
        stop_check()
    elif len(STOP_COMMAND) > 0:
        shell_rc, out_buf = cmd_fnc_u(STOP_COMMAND, quiet=quiet, show_err=0)
        if shell_rc != 0:
            print_timen("The caller wishes to stop test execution.")
            stop_check()

    rest_fail()

    esel_stop_check()

    qprint_timen("The caller does not wish to stop the test run.")
    return True


# Main

if not main():
    exit(1)
