package ru.dyatel.tsuschedule.parsing;

import org.junit.BeforeClass;
import org.junit.Test;
import ru.dyatel.tsuschedule.parsing.util.Filter;
import ru.dyatel.tsuschedule.parsing.util.IterableFilter;

import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class ParserTest {

    private Filter<Lesson> evenParity = new Filter<Lesson>() {
        @Override
        public boolean accept(Lesson obj) {
            return obj.getParity().equals(Parity.EVEN) || obj.getParity().equals(Parity.BOTH);
        }
    };
    private Filter<Lesson> oddParity = new Filter<Lesson>() {
        @Override
        public boolean accept(Lesson obj) {
            return obj.getParity().equals(Parity.ODD) || obj.getParity().equals(Parity.BOTH);
        }
    };
    private Filter<Lesson> firstSubgroup = new Filter<Lesson>() {
        @Override
        public boolean accept(Lesson obj) {
            return obj.getSubgroup() == 0 || obj.getSubgroup() == 1;
        }
    };

    private static Set<Lesson> lessons;

    @BeforeClass
    public static void setup() throws Exception {
        lessons = Parser.getLessons("221251");
    }

    @Test
    public void testGetLessonsMonday() throws Exception {
        IterableFilter<Lesson> filter = new IterableFilter<Lesson>();
        filter.apply(oddParity);
        filter.apply(new Filter<Lesson>() {
            @Override
            public boolean accept(Lesson obj) {
                return obj.getWeekday().equals("");
            }
        });
        filter.apply(firstSubgroup);

        Set<Lesson> result = filter.filter(lessons);
        assertEquals(3, result.size());
        assertTrue(containsDiscipline(result, ":"));
        assertTrue(containsDiscipline(result, ":"));
        assertTrue(containsDiscipline(result, ": "));
    }

    @Test
    public void testGetLessonsTuesday() throws Exception {
        IterableFilter<Lesson> filter = new IterableFilter<Lesson>();
        filter.apply(oddParity);
        filter.apply(new Filter<Lesson>() {
            @Override
            public boolean accept(Lesson obj) {
                return obj.getWeekday().equals("");
            }
        });
        filter.apply(firstSubgroup);

        Set<Lesson> result = filter.filter(lessons);
        assertEquals(3, result.size());
        assertTrue(containsDiscipline(result, " "));
        assertTrue(containsDiscipline(result, ": "));
        assertTrue(containsDiscipline(result, ":   "));
    }

    @Test
    public void testGetLessonsFridayEven() throws Exception {
        IterableFilter<Lesson> filter = new IterableFilter<Lesson>();
        filter.apply(evenParity);
        filter.apply(new Filter<Lesson>() {
            @Override
            public boolean accept(Lesson obj) {
                return obj.getWeekday().equals("");
            }
        });
        filter.apply(firstSubgroup);

        Set<Lesson> result = filter.filter(lessons);
        assertEquals(4, result.size());
        assertTrue(containsDiscipline(result, ": "));
        assertTrue(containsDiscipline(result, ":   "));
        Lesson lab = null;
        for (Lesson l : result) {
            if (l.getDiscipline().equals(":   ")) {
                lab = l;
                break;
            }
        }
        result.remove(lab);
        assertTrue(containsDiscipline(result, ":   "));
        assertTrue(containsDiscipline(result, ":   "));
    }

    @Test
    public void testGetLessonsFridayOdd() throws Exception {
        IterableFilter<Lesson> filter = new IterableFilter<Lesson>();
        filter.apply(oddParity);
        filter.apply(new Filter<Lesson>() {
            @Override
            public boolean accept(Lesson obj) {
                return obj.getWeekday().equals("");
            }
        });
        filter.apply(firstSubgroup);

        Set<Lesson> result = filter.filter(lessons);
        assertEquals(4, result.size());
        assertTrue(containsDiscipline(result, ": "));
        assertTrue(containsDiscipline(result, ":   "));
        Lesson lab = null;
        for (Lesson l : result) {
            if (l.getDiscipline().equals(":   ")) {
                lab = l;
                break;
            }
        }
        result.remove(lab);
        assertTrue(containsDiscipline(result, ":   "));
        assertTrue(containsDiscipline(result, ": "));
    }

    private boolean containsDiscipline(Set<Lesson> lessons, String discipline) {
        for (Lesson l : lessons) {
            if (l.getDiscipline().equals(discipline)) return true;
        }
        return false;
    }

}
@@ -3016,35 +3016,22 @@
         
-assertTrue(contains
+remove
 Discipli
@@ -3035,36 +3035,37 @@
 pline(result, %22:
+  
  %22)
-)
 ;%0A        assert
@@ -3068,260 +3068,31 @@
 sert
-True(containsDiscipline(result, %22:   %22));%0A        Lesson lab = null;%0A        for (Lesson l : result) %7B%0A            if (l.getDiscipline().equals(%22:   %22)) %7B%0A                lab = l;%0A                break;%0A            %7D%0A        %7D%0A        result.remove(lab
+Equals(2, result.size()
 );%0A 
@@ -3130,34 +3130,32 @@
 pline(result, %22:
-  
  %22));%0A        as
@@ -3696,32 +3696,114 @@
 result.size());%0A
+        removeDiscipline(result, %22:   %22);%0A        assertEquals(2, result.size());%0A
         assertTr
@@ -3880,34 +3880,32 @@
 pline(result, %22:
-  
  %22));%0A        Le
@@ -3902,30 +3902,91 @@
     
+%7D%0A%0A
     
+private boolean containsDiscipline(Set%3C
 Lesson
+%3E
  l
-ab = null;
+essons, String discipline) %7B
 %0A   
@@ -4006,22 +4006,23 @@
 son l : 
-result
+lessons
 ) %7B%0A    
@@ -4062,227 +4062,64 @@
 als(
-%22:   %22)) %7B%0A                lab = l;%0A                break;%0A            %7D%0A        %7D%0A        result.remove(lab);%0A        assertTrue(containsDiscipline(result, %22:   %22));%0A        assertTrue(containsDiscipline(result, %22: %22))
+discipline)) return true;%0A        %7D%0A        return false
 ;%0A  
@@ -4135,32 +4135,27 @@
 private 
-boolean contains
+void remove
 Discipli
@@ -4191,32 +4191,93 @@
 g discipline) %7B%0A
+        while (true) %7B%0A            Lesson lesson = null;%0A    
         for (Les
@@ -4287,32 +4287,36 @@
  l : lessons) %7B%0A
+    
             if (
@@ -4353,37 +4353,89 @@
 pline)) 
-return true;%0A
+%7B%0A                    lesson = l;%0A                    break;%0A    
         
 %7D%0A      
@@ -4418,32 +4418,36 @@
 ak;%0A            
+    
 %7D%0A        return
@@ -4436,34 +4436,116 @@
   %7D%0A        
-return false;
+    %7D%0A            if (lesson == null) break;%0A            else lessons.remove(lesson);%0A        %7D
 %0A    %7D%0A%0A%7D

Update ParserTest to be more convenient