"""
Used by each step as well as an entire step itself.
The classes defined in this file help with determining
the status of an individual test.

| author     = "Seth Miers"
| copyright  = "Copyright, Xilinx Inc. All rights reserved."
| credits    = ["Seth Miers"]
| license    = "GPL"
| version    = "3.0"
| maintainer = "Seth Miers"
| email      = "sethm@xilinx.com"
| status     = "Development"


"""

##########################################
#               Imports                  #
##########################################

# --------------Packages---------------- #
import re

# --------------Local------------------- #

##########################################
#              Main Code                 #
##########################################


class History:
    '''
    History is simply used to emulate a C struct.

    Attributes:
        time_run (int): the time the test was run
        passed (bool): if the test passed or not
        fail_cause (list): A list of the fail causes or
                           missing pass conditions
    '''
    # pylint: disable=too-few-public-methods
    # Considering how this class is designed
    # to emulate a C struct this is acceptable.
    # I don't want to use a namedtuple
    def __init__(self):
        self.time_started = 0
        self.time_ended = 0
        self.passed = False
        self.fail_cause = []

    def runtime(self):
        '''
        Use the start time and the end time to
        determine the entire runtime.

        Returns:
            int: the total runtime.
        '''
        return self.time_ended-self.time_started


class PassFail:
    '''
    PassFail is a class used to track the pass fail
    state of anything.

    Attributes:
        history (list): The history of all passes and fails
    '''
    def __init__(self):
        self.history = [History()]

    def run_count(self):
        '''
        Count the number of times this has been run.

        Returns:
            int: The run count
        '''
        return len(self.history)

    def pass_count(self):
        '''
        Count the number of passes in the history.

        Attributes:
            count: A temporary variable used
                to count the number of passes.

        Returns:
            int: The number of passes
        '''
        count = 0
        for history in self.history:
            if history.passed:
                count += 1
        return count

    def fail_count(self):
        '''
        Count the number of fails in the history.

        Attributes:
            count: A temporary variable used
                to count the number of fails.

        Returns:
            int: The number of fails
        '''
        count = 0
        for history in self.history:
            if not history.passed:
                count += 1
        return count


class CheckPassFail:
    '''
    Check for fail conditions and pass conditions in
    a block of text. 2 methods are used to return
    which condtions are not met.

    Args:
        pass_conditions (list): A list of regex strings
        fail_conditions (list): A list of regex strings

    Attributes:
        text (string): All the text to check against
    '''
    def __init__(self, pass_conditions, fail_conditions):
        self.pass_conditions = pass_conditions
        self.fail_conditions = fail_conditions
        self.text = ""

    def check_for_fail(self):
        '''
        Iterate through each of the fail_conditions then
        use regular expressions to check and see if that
        fail condition exists in the 'text' attribute

        Attributes:
            found_fail_conditions (list): A list of all the
                fail conditions that were found, returned
                back as the original regex.
        '''
        found_fail_conditions = []
        for fail_condition in self.fail_conditions:
            if re.findall(fail_condition, self.text, re.M | re.S):
                found_fail_conditions.append(fail_condition)
        return found_fail_conditions

    def check_for_pass(self):
        '''
        Iterate through each of the pass_conditions then
        use regular expressions to check and see if that
        pass condition exists in the 'text' attribute

        Attributes:
            missing_pass_conditions (list): A list of all the
                pass conditions that were not found, returned
                back as the original regex.
        '''
        missing_pass_conditions = self.pass_conditions
        for pass_condition in self.pass_conditions:
            if re.findall(pass_condition, self.text, re.M | re.S):
                missing_pass_conditions.remove(pass_condition)
        return missing_pass_conditions
