package eu.dnetlib.contract.cp.eval;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import eu.dnetlib.contract.cp.ICheckPoint;
import eu.dnetlib.contract.cp.ResultCheckPoint;
import eu.dnetlib.contract.cp.eval.module.ComplexEvaluatorModule;
import eu.dnetlib.contract.cp.eval.module.IEvaluatorModule;
import eu.dnetlib.contract.cp.eval.module.NotNullEvaluatorModule;
import eu.dnetlib.contract.cp.eval.module.RegexpStringEvaluatorModule;
import eu.dnetlib.contract.event.ExceptionContractEvent;
import eu.dnetlib.contract.event.IContractEvent;
import eu.dnetlib.contract.event.ResultContractEvent;
import eu.dnetlib.contract.node.EvaluationResult;
import eu.dnetlib.contract.node.EvaluationResult.Status;


/**
 * {@link ComplexEvaluatorModule} test class.
 * @author mhorst
 *
 */
public class ComplexEvaluatorModuleTest {

	ComplexEvaluatorModule module = null;
	ICheckPoint<IContractEvent> checkPoint = null;
	
	@Test
	public void testEvaluate() throws Exception {
		List<IEvaluatorModule<IContractEvent>> evaluatorModules;
		evaluatorModules = new ArrayList<IEvaluatorModule<IContractEvent>>();
		module = new ComplexEvaluatorModule();
		checkPoint = new ResultCheckPoint();
				
//		test null modules registered
		EvaluationResult result = module.evaluate(null, new ResultContractEvent(null, null), checkPoint);
		assertNotNull(result);
		assertEquals(Status.FAIL,result.getStatus());
//		test no modules registered
		module.setEvaluatorModules(evaluatorModules);
		result = module.evaluate(null, new ResultContractEvent(null, null), checkPoint);
		assertNotNull(result);
		assertEquals(Status.FAIL,result.getStatus());
		
		evaluatorModules.add(new NotNullEvaluatorModule());
		result = module.evaluate(null, new ResultContractEvent(null, null), checkPoint);
		assertNotNull(result);
		assertEquals(Status.FAIL,result.getStatus());
		
		evaluatorModules.clear();
		evaluatorModules.add(new NotNullEvaluatorModule());
		Object resultObject = new String();
		result = module.evaluate(resultObject, new ResultContractEvent(null, resultObject), checkPoint);
		assertNotNull(result);
		assertEquals(Status.OK,result.getStatus());
		
		evaluatorModules.clear();
		evaluatorModules.add(new NotNullEvaluatorModule());
		evaluatorModules.add(new NotNullEvaluatorModule());
		evaluatorModules.add(new NotNullEvaluatorModule());
		resultObject = new String();
		result = module.evaluate(resultObject, new ResultContractEvent(null, resultObject), checkPoint);
		assertNotNull(result);
		assertEquals(Status.OK,result.getStatus());
		
		evaluatorModules.clear();
		RegexpStringEvaluatorModule module = new RegexpStringEvaluatorModule();
		module.setRegexPattern("some(String|Other).*");
		evaluatorModules.add(new NotNullEvaluatorModule());
		evaluatorModules.add(module);
		resultObject = new String("someStringXXX");
		result = module.evaluate(resultObject, new ResultContractEvent(null, resultObject), checkPoint);
		assertNotNull(result);
		assertEquals(Status.OK,result.getStatus());
		
		evaluatorModules.clear();
		module = new RegexpStringEvaluatorModule();
		module.setRegexPattern("some(String|Other).*");
		evaluatorModules.add(new NotNullEvaluatorModule());
		evaluatorModules.add(module);
		resultObject = new String("blah");
		result = module.evaluate(resultObject, new ResultContractEvent(null, resultObject), checkPoint);
		assertNotNull(result);
		assertEquals(Status.FAIL,result.getStatus());
		
//		currently ContractEvent implementation is irrelevant
		evaluatorModules.clear();
		evaluatorModules.add(new NotNullEvaluatorModule());
		result = module.evaluate(null, new ExceptionContractEvent(null, null), checkPoint);
		assertNotNull(result);
		assertEquals(Status.FAIL,result.getStatus());

	}
}
