package eu.dnetlib.miscutils.functional;

import static org.junit.Assert.*;

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

import org.junit.Before;
import org.junit.Test;

import eu.dnetlib.miscutils.functional.ThreadSafeUnaryFunction;
import eu.dnetlib.miscutils.functional.UnaryFunction;

public class ThreadSafeUnaryFunctionTest {

	/**
	 * Object under test.
	 */
	private ThreadSafeUnaryFunction<String, Integer> tsUnaryFunction;
	
	private final static int N_THREAD = 10;
	
	private ExecutorService executor;
	
	@Before
	public void setUp() {
		executor = Executors.newFixedThreadPool(N_THREAD);
	}
	
	/**
	 * method creates N_THREAD threads such that each one performs a function.evaluate call
	 * @param function
	 */
	private void createThreads(final ThreadSafeUnaryFunction<String, Integer> function) {
		for (int i = 0; i < N_THREAD; i++) {
			final Integer j = i;
			executor.execute(new Runnable() {
				
				@Override
				public void run() {
					assertEquals(String.valueOf(j), function.evaluate(j));
				}
			});
		}	
	}	
	
	@Test
	public void testThreadSafeUnaryFunction_1() {
		tsUnaryFunction = new ThreadSafeUnaryFunction<String, Integer>(new ThreadLocal<UnaryFunction<String, Integer>>() {
		    @Override
			protected synchronized UnaryFunction<String, Integer> initialValue() {
		    	return new UnsafeUnaryFunction();
		    }
		});
		createThreads(tsUnaryFunction);			
	}
	
}
