package fr.umlv.examir2;

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

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.junit.Test;

@SuppressWarnings("static-method")
public class UtilsTest {
  @Test
  public void testGetFirstAsView() {
    assertTrue(Utils.getFirstAsView(1, Set.of()).isEmpty());
    assertTrue(Utils.getFirstAsView(0, Set.of("foo")).isEmpty());
    assertEquals(Set.of("bar"), Utils.getFirstAsView(1, Set.of("bar")));
  }
  
  @Test
  public void testGetFirstAsView2() {
    assertTrue(Utils.getFirstAsView(0, Set.of(1)).isEmpty());
    assertTrue(Utils.getFirstAsView(0, Set.of(1, 2, 3, 4)).isEmpty());
    assertEquals(Set.of(767), Utils.getFirstAsView(1, Set.of(767)));
  }
  
  @Test(expected = IndexOutOfBoundsException.class)
  public void testGetFirstAsViewInvalid() {
    Utils.getFirstAsView(-1, Set.of());
  }

  @Test
  public void testGetFirstAsViewBig() {
    Set<Integer> set = IntStream.range(0, 100).boxed().collect(Collectors.toSet());
    assertEquals(set, Utils.getFirstAsView(set.size(), set));
  }
  @Test
  public void testGetFirstAsViewBig2() {
    Set<Integer> set = IntStream.range(0, 100).boxed().collect(Collectors.toSet());
    ArrayList<Integer> list = new ArrayList<>(set);
    for(int i = 0; i < 50; i++) {
      list.remove(list.size() - 1);
    }
    assertEquals(list, new ArrayList<>(Utils.getFirstAsView(50, set)));
  }
  
  @Test
  public void testGetFirstAsViewCovariant() {
    class A { /* empty */ }
    class B extends A { /* empty */ }
    Set<A> set = Utils.getFirstAsView(0, Set.of(new B()));
    assertTrue(set.isEmpty());
  }
  
  @Test(expected = UnsupportedOperationException.class)
  public void testGetFirstAsViewImmutable() {
    Utils.getFirstAsView(1, Set.of("foo", "bar")).add("baz");
  }
  @Test(expected = UnsupportedOperationException.class)
  public void testGetFirstAsViewImmutable2() {
    Utils.getFirstAsView(2, Set.of("foo", "bar")).add("baz");
  }
  @Test(expected = UnsupportedOperationException.class)
  public void testGetFirstAsViewImmutable3() {
    Utils.getFirstAsView(3, Set.of("foo", "bar")).add("baz");
  }
  @Test(expected = UnsupportedOperationException.class)
  public void testGetFirstAsViewImmutable4() {
    Set<String> view = Utils.getFirstAsView(1, Set.of("foo", "bar"));
    Iterator<String> iterator = view.iterator();
    iterator.remove();
  }
}
