package fr.umlv.conc;

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import java.util.Random;

import static org.junit.jupiter.api.Assertions.*;

public class MinForkJoinTest {
  @Test @Tag("Q1")
  public void testMinLoop() {
    var array = new Random(0).ints(1_000_000, 0, Integer.MAX_VALUE).toArray();
    assertEquals(665, MinForkJoin.minLoop(array, 0, array.length));
  }
  @Test @Tag("Q1")
  public void testMinLoopRange() {
    var array = new Random(0).ints(1_000_000, 0, Integer.MAX_VALUE).toArray();
    assertEquals(2_956_155, MinForkJoin.minLoop(array, 500, 1_000));
  }
  @Test @Tag("Q1")
  public void testMinLoopPreconditions() {
    var array = new int[0];
    assertAll(
        () -> assertThrows(NullPointerException.class, () -> MinForkJoin.minLoop(null, 0, array.length)),
        () -> assertThrows(IllegalArgumentException.class, () -> MinForkJoin.minLoop(array, 0, array.length)),
        () -> assertThrows(IndexOutOfBoundsException.class, () -> MinForkJoin.minLoop(array, -1, array.length)),
        () -> assertThrows(IndexOutOfBoundsException.class, () -> MinForkJoin.minLoop(array, 0, 1))
    );
  }


  @Test @Tag("Q2")
  public void testMinStream() {
    var array = new Random(0).ints(1_000_000, 0, Integer.MAX_VALUE).toArray();
    assertEquals(665, MinForkJoin.minStream(array, 0, array.length));
  }
  @Test @Tag("Q2")
  public void testMinStreamRange() {
    var array = new Random(0).ints(1_000_000, 0, Integer.MAX_VALUE).toArray();
    assertEquals(2_956_155, MinForkJoin.minLoop(array, 500, 1_000));
  }
  @Test @Tag("Q2")
  public void testMinStreamPreconditions() {
    var array = new int[0];
    assertAll(
        () -> assertThrows(NullPointerException.class, () -> MinForkJoin.minStream(null, 0, array.length)),
        () -> assertThrows(IllegalArgumentException.class, () -> MinForkJoin.minStream(array, 0, array.length)),
        () -> assertThrows(IndexOutOfBoundsException.class, () -> MinForkJoin.minStream(array, -1, array.length)),
        () -> assertThrows(IndexOutOfBoundsException.class, () -> MinForkJoin.minStream(array, 0, 1))
    );
  }


  @Test @Tag("Q4")
  public void testMinForkJoin() {
    var array = new Random(0).ints(1_000_000, 0, Integer.MAX_VALUE).toArray();
    assertEquals(665, MinForkJoin.minForkJoin(array, 0, array.length));
  }
  @Test @Tag("Q4")
  public void testMinForkJoinRange() {
    var array = new Random(0).ints(1_000_000, 0, Integer.MAX_VALUE).toArray();
    assertEquals(2_956_155, MinForkJoin.minForkJoin(array, 500, 1_000));
  }
  @Test @Tag("Q4")
  public void testMinForkJoinPreconditions() {
    var array = new int[0];
    assertAll(
        () -> assertThrows(NullPointerException.class, () -> MinForkJoin.minForkJoin(null, 0, array.length)),
        () -> assertThrows(IllegalArgumentException.class, () -> MinForkJoin.minForkJoin(array, 0, array.length)),
        () -> assertThrows(IndexOutOfBoundsException.class, () -> MinForkJoin.minForkJoin(array, -1, array.length)),
        () -> assertThrows(IndexOutOfBoundsException.class, () -> MinForkJoin.minForkJoin(array, 0, 1))
    );
  }
}