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));

    }

}
