package fr.umlv.rental;

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

import java.util.HashSet;
import java.util.List;
import java.util.stream.IntStream;

import org.junit.Test;

@SuppressWarnings("static-method")
public class RentalTest {
  @Test
  public void newCar() {
    Car car = new Car("ford mustang", 2014);
    assertEquals("ford mustang", car.getModel());
  }

  @Test(expected = NullPointerException.class)
  public void newCarNoModel() {
    new Car(null, 2014);
  }
  
  @Test(expected=IllegalStateException.class)
  public void carRentalRemoveNotExist() {
    CarRental rental = new CarRental();
    rental.remove(new Car("ford mustang", 2013));
  }
  
  @Test(expected = NullPointerException.class)
  public void carRentalAddNull() {
    CarRental rental = new CarRental();
    rental.add(null);
  }
  
  public void carRentalAddALot() {
    CarRental rental = new CarRental();
    IntStream.range(0, 1_000_000).forEach(i -> rental.add(new Car("foo car", i)));
  }
  
  @Test
  public void carRentalAddRemove() {
    CarRental rental = new CarRental();
    rental.add(new Car("ford mustang", 2013));
    rental.remove(new Car("ford mustang", 2013));
    assertEquals("", rental.toString());
  }
  
  @Test
  public void carRentaltoString() {
    CarRental rental = new CarRental();
    rental.add(new Car("audi tt", 2001));
    rental.add(new Car("ford mustang", 2006));
    assertEquals("audi tt 2001\nford mustang 2006", rental.toString());
  }
  
  @Test
  public void carRentalFindAllByYear() {
    CarRental rental = new CarRental();
    rental.add(new Car("audi tt", 2012));
    rental.add(new Car("ford mustang", 2014));
    List<?> all = rental.findAllByYear(2014);
    assertTrue(all.contains(new Car("ford mustang", 2014)));
  }
  
  @Test
  public void carRentalFindAllByYearEmpty() {
    CarRental rental = new CarRental();
    rental.add(new Car("audi tt", 2015));
    rental.add(new Car("ford mustang", 2013));
    List<?> toSell = rental.findAllByYear(2014);
    assertTrue(toSell.isEmpty());
  }
  
  @Test
  public void newCamel() {
    Camel camel = new Camel(2014);
    assertEquals(camel, new Camel(2014));
  }
  
  @Test
  public void camelToString() {
    Camel camel = new Camel(2014);
    assertEquals("camel 2014", camel.toString());
  }
  
  @Test
  public void carRentalCarAndCamel() {
    CarRental rental = new CarRental();
    rental.add(new Car("ford mustang", 2014));
    rental.add(new Camel(2010));
    rental.remove(new Camel(2010));
    rental.remove(new Car("ford mustang", 2014));
  }
  
  @Test(expected = IllegalStateException.class)
  public void carRentalCarAndCamel2() {
    CarRental rental = new CarRental();
    rental.remove(new Camel(2010));
  }
  
  @Test
  public void carRentalCarAndCamelFindAllByYear() {
    CarRental rental = new CarRental();
    rental.add(new Car("ford mustang", 2010));
    rental.add(new Camel(2010));
    List<?> list = rental.findAllByYear(2010);
    assertTrue(list.contains(new Car("ford mustang", 2010)));
    assertTrue(list.contains(new Camel(2010)));
  }
  
  @Test
  public void carRentalCarAndCamelFindAllByYearInASet() {
    CarRental rental = new CarRental();
    rental.add(new Car("ford mustang", 2010));
    rental.add(new Camel(2010));
    List<?> list = rental.findAllByYear(2010);
    HashSet<?> set = new HashSet<>(list);
    assertTrue(set.contains(new Car("ford mustang", 2010)));
    assertTrue(set.contains(new Camel(2010)));
  }
  
  @Test(expected=NullPointerException.class)
  public void findACarByModelNull() {
    CarRental rental = new CarRental();
    rental.findACarByModel(null);
  }
  
  @Test
  public void findACarByModel() {
    CarRental rental = new CarRental();
    rental.add(new Car("ford mustang", 2020));
    rental.add(new Camel(2003));
    assertEquals(new Car("ford mustang", 2020), rental.findACarByModel("ford mustang").get());
  }
  
  @Test
  public void findACarByModel2() {
    CarRental rental = new CarRental();
    rental.add(new Car("renault alpine", 1992));
    rental.add(new Camel(1992));
    assertFalse(rental.findACarByModel("ford mustang").isPresent());
  }
}
