package ch.epfl.isochrone.timetable;

import static org.junit.Assert.assertEquals;

import java.util.Collections;

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

import ch.epfl.isochrone.geo.PointWGS84;

public class TestGraphEdge {
    // 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() {
        int i1 = GraphEdge.packTrip(0, 0);
        i1 = GraphEdge.unpackTripDepartureTime(0);
        i1 = GraphEdge.unpackTripDuration(0);
        i1 = GraphEdge.unpackTripArrivalTime(0) + i1;
        Stop s = null;
        GraphEdge e = new GraphEdge(s, 0, Collections.<Integer>emptySet());
        s = e.destination();
        i1 = e.earliestArrivalTime(0);

        GraphEdge.Builder b = new GraphEdge.Builder(s);
        b.setWalkingTime(0);
        b.addTrip(0, 0);
        e = b.build();
    }

    @Test (expected = IllegalArgumentException.class)
    public void tooSmallDepartureTime()
    {
        GraphEdge.packTrip(-10, 100);
    }
    
    @Test (expected = IllegalArgumentException.class)
    public void tooBigDepartureTime()
    {
        GraphEdge.packTrip(108000, 108001);
    }
    
    @Test (expected = IllegalArgumentException.class)
    public void tooSmallDurationTime()
    {
        GraphEdge.packTrip(102, 100);
    }
    
    @Test (expected = IllegalArgumentException.class)
    public void tooBigDurationTime()
    {
        GraphEdge.packTrip(1, 10001);
    }
    
    @Test
    public void unpackIsOk()
    {
        int a;
        int b;
        
        for (int i=0; i<1000; i++)
        {
            a = (int) (Math.random()*999);
            b = (int) (Math.random()*99);
            
            assertEquals(GraphEdge.unpackTripDepartureTime(GraphEdge.packTrip(a, a+b)),a);
            assertEquals(GraphEdge.unpackTripArrivalTime(GraphEdge.packTrip(a, a+b)),a+b);
            assertEquals(GraphEdge.unpackTripDuration(GraphEdge.packTrip(a, a+b)),b);
        }
    }
    
    @Test
    public void earliestArrivalTimeIsOk()
    {
        Stop s = new Stop("Arret", new PointWGS84(0.5,0.5));
        GraphEdge.Builder b1 = new GraphEdge.Builder(s);
        b1.setWalkingTime(SecondsPastMidnight.fromHMS(0, 10, 0)).addTrip(SecondsPastMidnight.fromHMS(0, 10, 0), SecondsPastMidnight.fromHMS(0, 15, 0));
        
        GraphEdge g1 = b1.build();
        
        assertEquals(g1.earliestArrivalTime(SecondsPastMidnight.fromHMS(0, 10, 0)), SecondsPastMidnight.fromHMS(0, 15, 0));
        assertEquals(g1.earliestArrivalTime(SecondsPastMidnight.fromHMS(0, 9, 0)), SecondsPastMidnight.fromHMS(0, 15, 0));
        assertEquals(g1.earliestArrivalTime(SecondsPastMidnight.fromHMS(0, 0, 0)), SecondsPastMidnight.fromHMS(0, 10, 0));
        
        
        
        GraphEdge.Builder b2 = new GraphEdge.Builder(s);
        b2.addTrip(SecondsPastMidnight.fromHMS(10, 10, 0), SecondsPastMidnight.fromHMS(10, 20, 0)).addTrip(SecondsPastMidnight.fromHMS(10, 40, 0), SecondsPastMidnight.fromHMS(10, 50, 0));
        
        GraphEdge g2 = b2.build();
        
        assertEquals(g2.earliestArrivalTime(SecondsPastMidnight.fromHMS(10, 0, 0)), SecondsPastMidnight.fromHMS(10, 20, 0));
        assertEquals(g2.earliestArrivalTime(SecondsPastMidnight.fromHMS(10, 10, 0)), SecondsPastMidnight.fromHMS(10, 20, 0));
        assertEquals(g2.earliestArrivalTime(SecondsPastMidnight.fromHMS(10, 10, 10)), SecondsPastMidnight.fromHMS(10, 50, 0));
        assertEquals(g2.earliestArrivalTime(SecondsPastMidnight.fromHMS(11, 0, 10)), SecondsPastMidnight.INFINITE);
        
        GraphEdge.Builder b3 = new GraphEdge.Builder(s);
        
        int a = (int) (Math.random()*59);
        int b = (int) (Math.random()*59);
        int c = (int) (Math.random()*600);
        
        for (int i=5; i<23; i++)
        {
            b3.addTrip(SecondsPastMidnight.fromHMS(i, a, b), SecondsPastMidnight.fromHMS(i, a, b)+c);
        }
        GraphEdge g3 = b3.build();
        
        assertEquals(g3.earliestArrivalTime(SecondsPastMidnight.fromHMS(1, 0, 0)), SecondsPastMidnight.fromHMS(5, a, b)+c);
        assertEquals(g3.earliestArrivalTime(SecondsPastMidnight.fromHMS(6, 0, 0)), SecondsPastMidnight.fromHMS(6, a, b)+c);
        assertEquals(g3.earliestArrivalTime(SecondsPastMidnight.fromHMS(23, 0, 0)), SecondsPastMidnight.INFINITE);
    }
}
