package org.threadly.concurrent.future;

import static org.junit.Assert.*;

import java.util.concurrent.CancellationException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;

import org.junit.Test;
import org.threadly.test.concurrent.AsyncVerifier;
import org.threadly.test.concurrent.TestCondition;

@SuppressWarnings("javadoc")
public class RunnableFutureCallbackAdapterTest {
  @Test
  public void constructorTest() {
    Future<Object> future = new TestFutureImp(false);
    FutureCallback<Object> callback = new TestFutureCallback();
    RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback);
    
    assertTrue(rfca.future == future);
    assertTrue(rfca.callback == callback);
  }
  
  @Test
  @SuppressWarnings("unused")
  public void constructorFail() {
    try {
      new RunnableFutureCallbackAdapter<>(null, new TestFutureCallback());
      fail("Exception should have thrown");
    } catch (IllegalArgumentException e) {
      // expected
    }
    try {
      new RunnableFutureCallbackAdapter<>(new TestFutureImp(false), null);
      fail("Exception should have thrown");
    } catch (IllegalArgumentException e) {
      // expected
    }
  }
  
  @Test
  public void resultTest() {
    SettableListenableFuture<Object> future = new SettableListenableFuture<>();
    TestFutureCallback callback = new TestFutureCallback();
    Object result = new Object();
    future.setResult(result);
    
    RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback);
    rfca.run();
    
    assertTrue(callback.getLastResult() == result);
    assertNull(callback.getLastFailure());
  }
  
  @Test
  public void executionExceptionTest() {
    SettableListenableFuture<Object> future = new SettableListenableFuture<>();
    TestFutureCallback callback = new TestFutureCallback();
    Exception failure = new Exception();
    future.setFailure(failure);
    
    RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback);
    rfca.run();
    
    assertTrue(callback.getLastFailure() == failure);
    assertNull(callback.getLastResult());
  }
  
  @Test
  public void cancellationExceptionTest() {
    Future<Object> future = new TestFutureImp(false);
    TestFutureCallback callback = new TestFutureCallback();
    future.cancel(true);
    
    RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback);
    rfca.run();
    
    assertTrue(callback.getLastFailure() instanceof CancellationException);
    assertNull(callback.getLastResult());
  }
  
  @Test
  public void interruptedExceptionTest() throws InterruptedException, TimeoutException {
    SettableListenableFuture<Object> future = new SettableListenableFuture<>();
    TestFutureCallback callback = new TestFutureCallback();
    final AsyncVerifier av = new AsyncVerifier();
    
    final RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback);
    final Thread t = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          rfca.run();
          av.fail("Exception did not throw");
        } catch (RuntimeException expected) {
          av.assertTrue(Thread.currentThread().isInterrupted());
          av.signalComplete();
        }
      }
    });
    
    t.start();
    new TestCondition(() -> t.isAlive()).blockTillTrue();
    
    t.interrupt();
    
    av.waitForTest();
    assertTrue(callback.getLastFailure() instanceof InterruptedException);
    assertNull(callback.getLastResult());
  }
}

@@ -347,16 +347,17 @@
 arnings(
+%7B
 %22javadoc
@@ -357,16 +357,32 @@
 javadoc%22
+, %22deprecation%22%7D
 )%0Apublic
@@ -3267,73 +3267,8 @@
 ) %7B%0A
-          av.assertTrue(Thread.currentThread().isInterrupted());%0A
     

Fix unit tests for recent deprecation / change