package ch.epfl.isochrone.timetable;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.junit.Ignore;
import org.junit.Test;

import ch.epfl.isochrone.timetable.Date.DayOfWeek;
import ch.epfl.isochrone.timetable.Date.Month;
import static org.junit.Assert.assertTrue;

public class TestService {
    // Le "test" suivant n'en est pas un à proprement parler, raison pour
    // laquelle il est ignoré (annotation @Ignore). Son seul but est de garantir
    // que les noms des classes et méthodes sont corrects.
    @Test
    @Ignore
    public void namesAreOk() {
        Date d = new Date(1, Month.JANUARY, 2000);
        Service s = new Service("s",
                d, d,
                Collections.<Date.DayOfWeek> emptySet(),
                Collections.<Date> emptySet(),
                Collections.<Date> emptySet());
        s.name();
        s.isOperatingOn(d);

        Service.Builder sb = new Service.Builder("s", d, d);
        sb.name();
        sb.addOperatingDay(DayOfWeek.MONDAY);
        sb.addExcludedDate(d);
        sb.addIncludedDate(d);
        sb.build();
    }
    
    @Test(expected = java.lang.IllegalArgumentException.class)
    public void tooEarlyIncludedDate() {
        Date d1 = new Date(10, Month.JANUARY, 2000);
        Date d2 = new Date(17, Month.FEBRUARY, 2001);
        Date d3 = new Date(1, Month.JANUARY, 2000);
        
        Service.Builder sb = new Service.Builder("s", d1, d2);
        
        sb.addIncludedDate(d3);
    }
    
    @Test(expected = java.lang.IllegalArgumentException.class)
    public void tooLateIncludedDate() {
        Date d1 = new Date(10, Month.JANUARY, 2000);
        Date d2 = new Date(17, Month.FEBRUARY, 2001);
        Date d3 = new Date(1, Month.JANUARY, 2002);
        
        Service.Builder sb = new Service.Builder("s", d1, d2);
        
        sb.addIncludedDate(d3);
    }
    
    @Test(expected = java.lang.IllegalArgumentException.class)
    public void tooEarlyExcludedDate() {
        Date d1 = new Date(10, Month.JANUARY, 2000);
        Date d2 = new Date(17, Month.FEBRUARY, 2001);
        Date d3 = new Date(1, Month.JANUARY, 2000);
        
        Service.Builder sb = new Service.Builder("s", d1, d2);
        
        sb.addExcludedDate(d3);
    }
    
    @Test(expected = java.lang.IllegalArgumentException.class)
    public void tooLateExcludedDate() {
        Date d1 = new Date(10, Month.JANUARY, 2000);
        Date d2 = new Date(17, Month.FEBRUARY, 2001);
        Date d3 = new Date(1, Month.JANUARY, 2002);
        
        Service.Builder sb = new Service.Builder("s", d1, d2);
        
        sb.addExcludedDate(d3);
    }
    
    @Test
    public void normalDate() {
        Date d1;
        Date d2;
        Date d3;
        Date d4;
        Date d5;
        
        boolean d3Diffd4;
        
        Service.Builder sb;
        Service s;
        Date.DayOfWeek dw;
        
        Month[] tabMonth= Month.values();
        
        for (int i=0; i<1000; i++)
        {
            int a = (int) Math.random()*9999;
            int b = (int) Math.random()*9999;
            int c = (int) Math.random()*9999;
            int d = (int) Math.random()*9999;
            
            d1 = new Date(a%28 + 1, tabMonth[a%12], 2000+a%10);
            d2 = new Date(b%28 + 1, tabMonth[b%12], 2020+b%10);
            d3 = new Date(c%28 + 1, tabMonth[c%12], 2010+c%10);
            d4 = new Date(d%28 + 1, tabMonth[d%12], 2010+d%10);
            
            sb = new Service.Builder("a", d1, d2);
            
            sb.addExcludedDate(d3);
            
            if (d3.compareTo(d4)!=0)
            {
                sb.addIncludedDate(d4);
                d3Diffd4=true;
                
            }
            else   
            {
                d3Diffd4=false;
            }
            
            dw=d3.dayOfWeek();
            sb.addOperatingDay(dw);
            
            s=sb.build();
            
            if(d3Diffd4)
            {
                assertTrue(s.isOperatingOn(d4));
            }
            assertTrue(!s.isOperatingOn(d3));
            
            
            d5 = new Date(3+dw.ordinal(),3,2014);
            if (d5.compareTo(d3)!=0)
            {
                assertTrue(s.isOperatingOn(d5));
            }
            
            
        }
    }
    
    @Test
    public void immua(){
        Set<Date> excludedDates = new HashSet<Date>();
        Set<Date.DayOfWeek> dayOfWeek = new HashSet<Date.DayOfWeek>();
        
        Date today=new Date(3,3,2014);
        excludedDates.add(today);
        dayOfWeek.add(Date.DayOfWeek.MONDAY);
        
        Service s = new Service("s",
                new Date(20,2,2014), new Date(20,3,2014),
                dayOfWeek,
                excludedDates,
                Collections.<Date> emptySet());
        
        excludedDates.remove(today);
        
        assertTrue(!s.isOperatingOn(today));
    }
}
