"""Pre-run modifier that excludes tests by their name.

Tests to exclude are specified by using a pattern that is both case and space
insensitive and supports '*' (match anything) and '?' (match single character)
as wildcards.
"""

from robot.api import SuiteVisitor
from robot.utils import Matcher
import re



class ExcludeTests(SuiteVisitor):

    def __init__(self, fname, flag):
        # load the suites file generated by the jenkins plug-in
        # the plugin lists suites to be excluded as java elements (ending with .class and .java)
        if int(flag)==1:
            self.include=True
        else:
            self.include=False

        with open(fname) as f:
            self.suites = f.readlines()
        self.suites = [x.strip() for x in self.suites ]
        #clean the java origin from the jenkins plugin
        self.suites = [re.sub(r'\.java$', '', l) for l in self.suites]
        self.suites = [re.sub(r'\.class$', '', l) for l in self.suites]
        #remove duplicates
        self.suites = list(set(self.suites))

    def start_suite(self, suite):

        """Remove suites that match the given list."""
       # print("*************" + self._suite_name_path(suite) + " **** " + str(len(suite.suites)))

        suite.suites = [s for s in suite.suites if self._to_keep(s)]

    def _to_keep(self, suite):
        if len(suite.suites)<>0: # always keep interim branches (the filter only applies to leaves)
            print(self._suite_name_path(suite) + "----- is not a leaf and has been kept")
            return True
        elif self.include:
            if self._suite_name_path(suite) in self.suites: # keep matching suites in case of include file
                print(self._suite_name_path(suite) + "----- is a leaf and has been kept (include file)")
                return True
            else:
                print(self._suite_name_path(suite) + "----- is a leaf and has been dropped (include file)")
                return False
        else:
            if not self._suite_name_path(suite) in self.suites: # do not keep matching suites in case of exclude file
                print(self._suite_name_path(suite) + "----- is a leaf and has been kept (exclude file)")
                return True
            else:
                print(self._suite_name_path(suite) + "----- is a leaf and has been dropped (exclude file)")
                return False


    def _suite_name_path(self, suite):
        """Returns the full path and name of the current test suite"""
        sfpath=suite.name
        parent = suite.parent
        while not parent is None:
            sfpath=parent.name + '/' + sfpath
            parent = parent.parent
        return sfpath


    def end_suite(self, suite):
        """Remove suites that are empty after removing tests."""
        suite.suites = [s for s in suite.suites if s.test_count > 0]

    def visit_test(self, test):
        """Avoid visiting tests and their keywords to save a little time."""
        pass
