

package gov.va.med.tfs.junit.runners;


import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;

import java.util.Arrays;
import java.util.List;


public final class GroupAwareFilter
    extends
        Filter
{

    private static final String TEST_GROUPS = "cds.test.groups";
    private static final String DELIMITER = ",";

    private List<String> testGroupNames;


    public GroupAwareFilter( )
    {
        super();
        if ( hasTestGroups() )
            testGroupNames = getTestGroupNames();
    }


    @Override
    public String describe( )
    {
        return "Filters out all tests not explicitly named in a comma-delimited list in the system property 'cds.test.groups'.";
    }


    @Override
    public boolean shouldRun( Description d )
    {
        if ( testGroupNames == null )
        {
            return true;
        }

        // Run the BeforeTestsOnce and AfterTestsOnce annotations always 
        if (d.getAnnotation( RunnerUtils.BEFORE_TESTS_ONCE) != null || d.getAnnotation( RunnerUtils.AFTER_TESTS_ONCE) != null) 
            return true;
        
        String[] groups = ( d.getAnnotation( RunnerUtils.MARKER_CLASS ) != null ) ? ( d.getAnnotation( RunnerUtils.MARKER_CLASS ) )
                        .groups() : null;
                        

        if ( groups == null || groups.length == 0 )
        {
            return false;
        }
        return testGroupNames.containsAll( Arrays.asList( groups ) );
    }


    public static boolean hasTestGroups( )
    {

        return System.getProperty( TEST_GROUPS ) != null;
    }


    private static List<String> getTestGroupNames( )
    {

        if ( System.getProperty( TEST_GROUPS ) == null )
        {
            throw new NullPointerException( "Test groups property is not set" );
        }
        String testCases = System.getProperty( TEST_GROUPS );
        return Arrays.asList( testCases.split( DELIMITER ) );
    }
}
