import static org.junit.Assert.assertTrue; // import static : une facilité offerte depuis java5 (pas besoin de mettre le préfixe)
import static org.junit.Assert.assertFalse; //
import static org.junit.Assert.assertSame; //
import org.junit.Test;


import java.util.NoSuchElementException;
import java.util.Random;


/**
 * Une classe pour faire des tests sur la classe SimpleDeque avec JUnit
 * On utlise des string comme type paramétré.
 */
public class TestSimpleDeque {


    /**
     * On ne peut pas ajouter avec addFirst l'élément null 
     * [0.5 point]
     */
    @Test(expected = NullPointerException.class)
    public void addFirstNull(){
	MinimalDeque<String> d = new SimpleDeque<String>();
	
        d.addFirst(null);
    }

    /**
     * On ne peut pas ajouter avec addLast l'élément null 
     * [0.5 point]
     */
    @Test(expected = NullPointerException.class)
    public void addLastNull(){
        MinimalDeque<String> d = new SimpleDeque<String>();
        d.addLast(null);

    }
    
    /**
     * Un deque sans élément est vide.
     * [0.5 point]
     */
    @Test
    public void addNoneIsEmpty(){
        MinimalDeque<String> d = new SimpleDeque<String>();
        assertTrue(d.isEmpty());
    }
    
    /**
     * Un deque avec 1 élément n'est pas vide.
     * [0.5 point]
     */
    @Test
    public void addOneIsNotEmpty(){
        MinimalDeque<String> d = new SimpleDeque<String>();
        d.addFirst("meu");
        assertFalse(d.isEmpty());

    }

    
    /**
     * Dans un deque vide ajouter devant "ga" "bu" "zo" "meu" devant puis enlever à la fin me redonne les mêmes string (identiques aux précédents) et dans le même ordre. 
     * [1 point]
     */
    @Test
    public void pasDeResquilleur(){
	MinimalDeque<String> d = new SimpleDeque<String>();
	String ga = "ga";
	String bu = "bu";
	String zo = "zo";
	String meu = "meu";
    d.addFirst(ga);
    d.addFirst(bu);
    d.addFirst(zo);
    d.addFirst(meu);
    assertSame(ga,d.removeLast());
    assertSame(bu,d.removeLast());
    assertSame(zo,d.removeLast());
    assertSame(meu,d.removeLast());

    }

    /**
     * Dans un deque vide ajouter "ga" "bu" "zo" "meu" derrière puis enlever au débutr me redonne les mêmes string (identiques aux précédents) et dans le même ordre. 
     * [1 point]
     */
    @Test
    public void pasDeResquilleurQuantique(){
        MinimalDeque<String> d = new SimpleDeque<String>();
        String ga = "ga";
        String bu = "bu";
        String zo = "zo";
        String meu = "meu";
        d.addLast(ga);
        d.addLast(bu);
        d.addLast(zo);
        d.addLast(meu);
        assertSame(ga,d.removeFirst());
        assertSame(bu,d.removeFirst());
        assertSame(zo,d.removeFirst());
        assertSame(meu,d.removeFirst());
    }

    /**
     * On ne peut pas enlever d'élément devant d'un deque vide.
     * [1 point]
     */
    @Test(expected = NullPointerException.class)
    public void removeFirstFromEmpty(){
        MinimalDeque<String> d = new SimpleDeque<String>();
        d.removeFirst();
    }    

    /**
     * On ne peut pas enlever d'élément derrière d'un deque vide.
     * [1 point]
     */
    @Test(expected = NullPointerException.class)
    public void removeLastFromEmpty(){
        MinimalDeque<String> d = new SimpleDeque<String>();
        d.removeLast();
    }    

    /**
     * Dans un deque vide ajouter "ga" puis enlever me redonne le même string que ajouter ou enlever soit devant oui derrière. 
     * [2 point]
     */
    @Test
    public void mangerLaBananeParLesDeuxBouts(){
	    MinimalDeque<String> d = new SimpleDeque<String>();
	    String ga = "ga";
        String ga1, ga2;
        d.addFirst(ga);
        ga1 = d.removeFirst();
        d.addLast(ga);
        ga2 = d.removeLast();
        assertSame(ga1,ga2);

    }


    /**
     * Invariant de taille
     * Lancer un nombre entier aléatoire N compris entre 100 et 1000 (inclus).
     *
     * Ajouter au hasard, devant ou derrière N éléments tirés au hasard dans {"Ga", "bu", "zo", "meu"}.
     *
     * Enlever au hasard, devant ou derrière N éléments.
     *
     * Vérifier finalement que la Deque est vide.
     *
     * [4 point]
     */
    @Test
    public void invariantTaille(){
	MinimalDeque<String> d = new SimpleDeque<String>();
	String[] s = {"ga","bu","zo","meu"};
	Random rd = new Random();

	int N = rd.nextInt(900)+100;
    int i;
    for (i=0; i<N; i++){
        int indice = rd.nextInt(3);
        d.addFirst(s[indice]);
    }
    for (i=0; i<N; i++){
        d.removeLast();
    }
    assertTrue(d.isEmpty());

	// rd.nextBoolean())

	
	// s[rd.nextInt(4)])
	
    }

    

    
}