#!/usr/bin/env python3

r"""
Use robot framework API to extract test data from test suites.
Refer to https://robot-framework.readthedocs.io/en/latest/autodoc/robot.running.html
"""

import os
import sys

from robot.api import SuiteVisitor, TestSuiteBuilder

sys.path.append(os.path.join(os.path.dirname(__file__), "../lib"))

from gen_arg import *  # NOQA
from gen_print import *  # NOQA
from gen_valid import *  # NOQA

# Set exit_on_error for gen_valid functions.
set_exit_on_error(True)

valid_options = ["name", "tags", "doc", "all"]

parser = argparse.ArgumentParser(
    usage="%(prog)s [OPTIONS]",
    description=(
        ";%(prog)s will print test suite information to stdout. This          "
        "         information consists of any and/or all of the following:    "
        "               the suite name, test case names, tag names and doc"
        " strings.                   Example for generated test case names    "
        "               tests/test_basic_poweron.robot                  "
        " Verify Front And Rear LED At Standby                   Power On Test"
        "                   Check For Application Failures                  "
        " Verify Uptime Average Against Threshold                   Test SSH"
        " And IPMI Connections"
    ),
    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    prefix_chars="-+",
)

parser.add_argument(
    "--source_path", "-s", help="The robot test file or directory path."
)

parser.add_argument(
    "--option",
    "-o",
    default="name",
    help="Test case attribute name.  This may be any one of the following:\n"
    + sprint_var(valid_options),
)

# Populate stock_list with options we want.
stock_list = [("test_mode", 0), ("quiet", 0), ("debug", 0)]


class TestPrint(SuiteVisitor):

    def __init__(self, option):
        self.option = option

    def visit_test(self, test):
        r"""
        Print the test data from suite test object from option specified.
        """
        if self.option == "name":
            print(test.name)
        elif self.option == "tags":
            print(test.tags)
        elif self.option == "doc":
            print(test.doc)
        elif self.option == "all":
            print(test.name)
            print(test.tags)
            print(test.doc)


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, the
    program would terminate immediately with return code 143 and without
    calling the 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 the signal was received.
    exit(0)


def validate_parms():
    r"""
    Validate program parameters, etc.  Return True or False (i.e. pass/fail)
    accordingly.
    """

    valid_path(source_path)

    valid_value(option, valid_values=valid_options)

    gen_post_validation(exit_function, signal_handler)


def parse_test_suites(source_path, option):
    r"""
    Parse the robot files and extract test data output.

    Description of argument(s):
    source_path   The path to a robot file or a directory of robot files.
    option        Test case attribute instances such as "name",
                  "tags" or "doc".
    """
    if os.path.isfile(source_path):
        file_paths = [source_path]
    else:
        file_paths = [
            os.path.join(path, file)
            for (path, dirs, files) in os.walk(source_path)
            for file in files
        ]

    for file_path in file_paths:
        print(file_path)
        if "__init__.robot" in file_path:
            continue
        test_suite_obj = TestSuiteBuilder().build(file_path)
        parse_test_file(test_suite_obj, option)


def parse_test_file(test_suite_obj, option):
    r"""
    Extract test information from test suite object and print it to stdout in
    the following format:

    <Test Case name>
    <Test Tags name>
    <Test Documentation>

    Description of argument(s):
    test_suite_obj    Test data suite object.
    option            Test case attribute instances such as "name",
                      "tags" or "doc".
    """

    test_suite_obj.visit(TestPrint(option))


def main():
    gen_get_options(parser, stock_list)

    validate_parms()

    qprint_pgm_header()

    parse_test_suites(source_path, option)

    return True


# Main
main()
