#!/usr/bin/env python3

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

import sys
import os
from robot.parsing.model import TestData
sys.path.append(os.path.join(os.path.dirname(__file__), "../lib"))

from gen_arg import *
from gen_print import *
from gen_valid import *

# 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)]


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 = TestData(parent=None, source=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".
    """

    for testcase in test_suite_obj.testcase_table:
        if option == "name":
            print(testcase.name)
        elif option == "tags":
            print(testcase.tags)
        elif option == "doc":
            print(testcase.doc)
        elif option == "all":
            print(testcase.name)
            print(testcase.tags)
            print(testcase.doc)


def main():

    gen_get_options(parser, stock_list)

    validate_parms()

    qprint_pgm_header()

    parse_test_suites(source_path, option)

    return True


# Main
main()
