package org.test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;

public class TraitTest {
	List<Integer> trueTraits;
	List<Integer> untrueTraits;
	KnowledgeRuntimeLogger klogger;
	@Rule public TestName testName = new TestName();

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		File r = new File("results");
		if (!r.isDirectory()) {
			System.out.println("Creating results directory");
			r.mkdir();
		}
		for (File f : r.listFiles()) {
			try {
				f.delete();
			} catch (Exception e) {
				System.err.println("Could not delete results file " + f);
			}
		}
	}
	
	@Before
	public void setUp() throws Exception {
		trueTraits = new ArrayList<Integer>();
		untrueTraits = new ArrayList<Integer>();
	}
	
	@After
	public void tearDown() throws Exception {
		if (null != klogger) klogger.close();
		klogger = null;
	}
	
	private StatefulKnowledgeSession getSession(String... ruleFiles) {
		KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		for (String file : ruleFiles) {
			knowledgeBuilder.add(ResourceFactory.newClassPathResource(file), ResourceType.DRL);
		}		
		if (knowledgeBuilder.hasErrors()) {
			throw new RuntimeException(knowledgeBuilder.getErrors().toString());
		}

		KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
		kbase.addKnowledgePackages(knowledgeBuilder.getKnowledgePackages());
		
		StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession();
		session.setGlobal("trueTraits", trueTraits);
		session.setGlobal("untrueTraits", untrueTraits);
		
		klogger = KnowledgeRuntimeLoggerFactory.newFileLogger(session, "results/" + testName.getMethodName());
		
		return session;
	}
	
	@Test
	public void declaredTest() {
		StatefulKnowledgeSession session = getSession("org/test/declared-fact-trait-test.drl");
		session.fireAllRules();
		session.dispose();
		
		assertTrue(trueTraits.contains(1));
		assertFalse(trueTraits.contains(2));
		assertTrue(untrueTraits.contains(2));
		assertFalse(untrueTraits.contains(1));
	}
	
	@Test
	public void pojoTest() {
		StatefulKnowledgeSession session = getSession("org/test/pojo-fact-trait-test.drl");
		session.fireAllRules();
		session.dispose();
		
		assertTrue(trueTraits.contains(1));
		assertFalse(trueTraits.contains(2));
		assertTrue(untrueTraits.contains(2));
		assertFalse(untrueTraits.contains(1));
	}
}