package com.edwise.pocs.completablefuturepoc;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class CompletableFutureTest {
    private final static Logger LOGGER = LoggerFactory.getLogger(CompletableFutureTest.class);

    private static ExecutorService executor;

    @BeforeClass
    public static void setUp() {
        executor = Executors.newFixedThreadPool(5);
    }

    @AfterClass
    public static void shutDown() throws InterruptedException {
        executor.shutdown();
        executor.awaitTermination(10, TimeUnit.SECONDS);
    }

    @Test
    public void testFutureCreationNewCompleted() {
        CompletableFuture<String> future = CompletableFuture.completedFuture("Prueba");
        LOGGER.info("Completable creado.");

        future.whenCompleteAsync((s, e) -> LOGGER.info("Result: " + s), executor);
    }

    @Test
    public void testFutureCreationNew() {
        CompletableFuture<String> future = new CompletableFuture<>();
        LOGGER.info("Completable creado.");

        future.whenCompleteAsync((s, e) -> LOGGER.info("Result: " + s), executor);
        LOGGER.info("Registrado el when complete...");

        Sleep.sleepSeconds(2);
        future.complete("Completado!");
    }

    @Test
    public void testFutureCreationRunAsync() {
        CompletableFuture<Void> futureAsync = CompletableFuture.runAsync(() -> {
            LOGGER.info("Comenzando runAsync...");
            Sleep.sleepSeconds(3);
            LOGGER.info("Terminado runAsync!");
        }, executor);

        futureAsync.whenCompleteAsync((s, e) -> LOGGER.info("Sin resultado..."), executor);
        LOGGER.info("Terminado main thread");
    }

    @Test
    public void testFutureCreationSupplyAsync() {
        CompletableFuture<String> futureAsync = CompletableFuture.supplyAsync(() -> {
            LOGGER.info("Comenzando supplyAsync...");
            Sleep.sleepSeconds(3);
            LOGGER.info("Terminado supplyAsync!");
            return "Terminado";
        }, executor);

        futureAsync.whenCompleteAsync((s, e) -> LOGGER.info("Resultado supplyAsync: " + s), executor);
        LOGGER.info("Terminado main thread");
    }

    @Test
    public void testFutureCreationSupplyAsyncBlocking() throws Exception {
        CompletableFuture<String> futureAsync = CompletableFuture.supplyAsync(() -> {
            LOGGER.info("Comenzando supplyAsyncBlocking...");
            Sleep.sleepSeconds(3);
            LOGGER.info("Terminado supplyAsyncBlocking!");
            return "Terminado";
        }, executor);

        LOGGER.info("Resultado bloqueando supplyAsync: " + futureAsync.get());
    }
}
@@ -710,32 +710,63 @@
 ptedException %7B%0A
+        Sleep.sleepSeconds(5);%0A
         executor
@@ -816,10 +816,9 @@
 ion(
-10
+5
 , Ti
@@ -2373,32 +2373,48 @@
 lyAsync: %22 + s),
+%0A               
  executor);%0A    

fix for executor shutdown.