#!/usr/bin/env python

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()
