package com.agilex.healthcare.schedulingmanager.datalayer.fork;

import java.util.concurrent.TimeUnit;

import jsr166y.ForkJoinPool;
import jsr166y.RecursiveTask;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This class create a ForkJoinPool with the default number of threads, which is the number of
 * CPU cores of the host system. It is intended to be used as the base class for task-specific Fork/Join runners.
 *
 * @param <V> The return type of the Fork/Join task.
 */
public abstract class ForkJoinTaskRunner<V> {
    
    private final Log logger = LogFactory.getLog(ForkJoinTaskRunner.class);

    public V runJob(final RecursiveTask<V> task) {
        ForkJoinPool pool = new ForkJoinPool();
        pool.execute(task);

        if (logger.isDebugEnabled()) {
            do {
                logger.debug(String.format("\n******************************************\n" +
                                           "Main: Parallelism: %d\n" +
                                           "Main: Active Threads: %d\n" +
                                           "Main: Task Count: %d\n" +
                                           "Main: Steal Count: %d\n" +
                                           "******************************************\n",
                                pool.getParallelism(), pool.getActiveThreadCount(), pool.getQueuedTaskCount(), pool.getStealCount())
                );

                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } while (!task.isDone());
        }
        
        pool.shutdown();
        return task.join();
    }
}
