package net.jodah.failsafe.internal.util;

import net.jodah.concurrentunit.Waiter;
import net.jodah.failsafe.Asserts;
import net.jodah.failsafe.util.concurrent.Scheduler;
import org.testng.annotations.Test;

import java.io.IOException;
import java.time.Duration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import static org.testng.Assert.assertTrue;
import static org.testng.Assert.*;

@Test
public class DelegatingSchedulerTest {
  Scheduler scheduler = DelegatingScheduler.INSTANCE;

  public void shouldSchedule() throws Throwable {
    // Given
    Duration delay = Duration.ofMillis(200);
    Waiter waiter = new Waiter();
    long startTime = System.nanoTime();

    // When
    scheduler.schedule(() -> {
      waiter.resume();
      return null;
    }, delay.toMillis(), TimeUnit.MILLISECONDS);

    // Then
    waiter.await(1000);
    assertTrue(System.nanoTime() - startTime > delay.toNanos());
  }

  public void shouldWrapCheckedExceptions() {
    Asserts.assertThrows(() -> scheduler.schedule(() -> {
      throw new IOException();
    }, 1, TimeUnit.MILLISECONDS).get(), ExecutionException.class, IOException.class);
  }

  public void shouldNotInterruptAlreadyDoneTask() throws Throwable {
    Waiter waiter = new Waiter();
    Future<?> future1 = scheduler.schedule(() -> null, 0, TimeUnit.MILLISECONDS);
    Future<?> future2 = scheduler.schedule(() -> {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        waiter.fail("Cancelling one future should not interrupt another");
      }
      waiter.resume();
      return null;
    }, 0, TimeUnit.MILLISECONDS);
    Thread.sleep(100);
    assertFalse(future1.cancel(true));
    waiter.await(1000);
  }
}

@@ -284,34 +284,17 @@
 current.
-ExecutionException
+*
 ;%0Aimport
@@ -319,52 +319,30 @@
 ent.
-Future;%0Aimport java.util.concurrent.TimeUnit
+atomic.AtomicReference
 ;%0A%0Ai
@@ -378,19 +378,20 @@
 t.assert
-Tru
+Fals
 e;%0Aimpor
@@ -417,17 +417,26 @@
 .Assert.
-*
+assertTrue
 ;%0A%0A@Test
@@ -1745,11 +1745,840 @@
 00);%0A  %7D
+%0A%0A  /**%0A   * Asserts that ForkJoinPool clears interrupt flags.%0A   */%0A  public void shouldClearInterruptFlagInForkJoinPoolThreads() throws Throwable %7B%0A    Scheduler scheduler = new DelegatingScheduler(new ForkJoinPool(1));%0A    AtomicReference%3CThread%3E threadRef = new AtomicReference%3C%3E();%0A    Waiter waiter = new Waiter();%0A%0A    // Create interruptable execution%0A    scheduler.schedule(() -%3E %7B%0A      threadRef.set(Thread.currentThread());%0A      waiter.resume();%0A      Thread.sleep(10000);%0A      return null;%0A    %7D, 0, TimeUnit.MILLISECONDS);%0A    waiter.await(1000);%0A    threadRef.get().interrupt();%0A%0A    // Check for interrupt flag%0A    scheduler.schedule(() -%3E %7B%0A      waiter.assertFalse(Thread.currentThread().isInterrupted());%0A      waiter.resume();%0A      return null;%0A    %7D, 0, TimeUnit.MILLISECONDS);%0A    waiter.await(1000);%0A  %7D
 %0A%7D%0A

Add test to assert that ForkJoinPool clears interrupt flags