package ch.epfl.isochrone.timetable;

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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

import ch.epfl.isochrone.geo.PointWGS84;

public class TestFastestPathTree {
    // 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() {
        Stop stop = null;
        Map<Stop, Integer> arrivalTimes = null;
        Map<Stop, Stop> predecessors = null;
        FastestPathTree f = new FastestPathTree(stop, arrivalTimes, predecessors);
        Stop s = f.startingStop();
        int i = f.startingTime();
        Set<Stop> ss = f.stops();
        i = f.arrivalTime(stop);
        List<Stop> p = f.pathTo(stop);
        System.out.println("" + s + i + ss + p);

        FastestPathTree.Builder fb = new FastestPathTree.Builder(stop, 0);
        fb.setArrivalTime(stop, 0, stop);
        i = fb.arrivalTime(stop);
        f = fb.build();
    }
   
   @Test 
   public void testArrivalTime(){
       Stop stop1 = new Stop("Arret", new PointWGS84(0.5,0.5));
       Stop stop2 = new Stop("Arret2", new PointWGS84(0.2,0.2)); 
       Stop stop3 = new Stop("Arret3", new PointWGS84(0.4,0.4)); 
     
       Map<Stop, Integer> arrivalTimes = new HashMap<Stop, Integer>();
       Map<Stop, Stop> predecessors = new HashMap<Stop, Stop>();
       arrivalTimes.put(stop1, 0);
       arrivalTimes.put(stop2, 1);
       arrivalTimes.put(stop3, 3);
       
       predecessors.put(stop2, stop1);
       predecessors.put(stop3, stop2);
       FastestPathTree f = new FastestPathTree(stop1, arrivalTimes, predecessors);
       
       assertEquals(f.arrivalTime(stop1),0);
       assertEquals(f.arrivalTime(stop2),1);
       assertEquals(f.arrivalTime(stop3),3);
   }
   
   @Test(expected = IllegalArgumentException.class)
   public void testpathToThrow(){
       Stop stop = new Stop("Arret", new PointWGS84(0.5,0.5));
       Map<Stop, Integer> arrivalTimes = new HashMap<Stop, Integer>();
       Map<Stop, Stop> predecessors = new HashMap<Stop, Stop>();
       @SuppressWarnings("unused")
    FastestPathTree f = new FastestPathTree(stop, arrivalTimes, predecessors);
   }
   
   @Test
   public void testpathTo(){
       Stop stop1 = new Stop("Arret", new PointWGS84(0.5,0.5));
       Stop stop2 = new Stop("Arret2", new PointWGS84(0.2,0.2)); 
       Stop stop3 = new Stop("Arret3", new PointWGS84(0.4,0.4)); 
     
       Map<Stop, Integer> arrivalTimes = new HashMap<Stop, Integer>();
       Map<Stop, Stop> predecessors = new HashMap<Stop, Stop>();
       arrivalTimes.put(stop1, 0);
       arrivalTimes.put(stop2, 1);
       arrivalTimes.put(stop3, 3);
       
       predecessors.put(stop2, stop1);
       predecessors.put(stop3, stop2);
       FastestPathTree f = new FastestPathTree(stop1, arrivalTimes, predecessors);
       
       List<Stop> liste = new ArrayList<Stop>();
       liste.add(stop1);
       liste.add(stop2);
       liste.add(stop3);
       
       assertEquals(liste, f.pathTo(stop3));
       
   }
   
   
   @Test
   public void testImmu(){
       Stop stop = new Stop("Arret", new PointWGS84(0.5,0.5));
       Map<Stop, Integer> arrivalTimes = new HashMap<Stop, Integer>();
       Map<Stop, Stop> predecessors = new HashMap<Stop, Stop>();
       arrivalTimes.put(stop, 0);
       FastestPathTree f = new FastestPathTree(stop, arrivalTimes, predecessors);
       
       Set<Stop> set = f.stops();
       set.clear();
       
       assertTrue(!(set.equals(f.stops())));
   }
   
   @Test (expected = IllegalArgumentException.class)
   public void testBuilderThrow1(){
       Stop stop1 = new Stop("Arret", new PointWGS84(0.5,0.5));
       FastestPathTree.Builder fb = new FastestPathTree.Builder(stop1, -10);
       fb.build();

   }
   
   @Test (expected = IllegalArgumentException.class)
   public void testBuilderThrow2(){
       Stop stop1 = new Stop("Arret", new PointWGS84(0.5,0.5));
       FastestPathTree.Builder fb = new FastestPathTree.Builder(stop1, 10);
       Stop stop2 = new Stop("Arret2", new PointWGS84(0.6,0.5));
       fb.setArrivalTime(stop2, 0, stop1);

   }
   
   @Test
   public void testBuilderOk(){
       Stop stop1 = new Stop("Arret", new PointWGS84(0.5,0.5));
       Stop stop2 = new Stop("Arret2", new PointWGS84(0.2,0.2)); 
       Stop stop3 = new Stop("Arret3", new PointWGS84(0.4,0.4)); 
       
       FastestPathTree.Builder fb = new FastestPathTree.Builder(stop1, 10);

       FastestPathTree f = fb.setArrivalTime(stop2, 15, stop1).setArrivalTime(stop3, 20, stop2).build();
       
       List<Stop> liste = new ArrayList<Stop>();
       liste.add(stop1);
       liste.add(stop2);
       liste.add(stop3);
       
       assertEquals(liste, f.pathTo(stop3));

   }
   
}
