package csp;

import org.junit.Ignore;
import org.junit.Test;

import edu.neu.ccs.demeterf.lib.None;
import edu.neu.ccs.demeterf.lib.Option;
import edu.neu.ccs.demeterf.lib.Some;
import junit.framework.Assert;
import scg.Claim;
import scg.InstanceI;
import scg.InstanceSetI;
import scg.SolutionI;
import scg.protocol.ForAllExists;

public class TestCSP {

	@Test
	public void testCSPInstance() throws Exception {
		final String inpt = "x1 x2 x3  (12 {1} x1 x2 x3 ) ";
		InstanceI instance = CSPInstance.parse(inpt);
		Assert.assertTrue(instance instanceof CSPInstance);
		CSPInstance cspInstance = (CSPInstance) instance;
		Clause first = cspInstance.getClauses().first;
		Assert.assertEquals(12, first.getRelnum());
		Assert.assertEquals(inpt, cspInstance.print());
	}
	
	
	@Test
	public void testCSPSolution() throws Exception {
		final String inpt = "[ (x1 -> true) (x2 -> true) (x3 -> true)  ]";
		SolutionI solution = CSPSolution.parse(inpt);
		Assert.assertTrue(solution instanceof CSPSolution);
		CSPSolution cspSolution = (CSPSolution) solution;
		int size = cspSolution.getAssign().size();
		Assert.assertEquals(3, size);
		Assert.assertEquals(inpt, cspSolution.print());
	}
	
	@Test
	public void testCSPInstanceSet() throws Exception {
		String inpt = "(20 21 22 )";
		InstanceSetI instanceSet = CSPInstanceSet.parse(inpt);
		Assert.assertTrue(instanceSet instanceof CSPInstanceSet);
		CSPInstanceSet cspInstanceSet = (CSPInstanceSet)instanceSet;
		int size = cspInstanceSet.getType().size();
		Assert.assertEquals(3, size);
		Assert.assertEquals(inpt, cspInstanceSet.print());
		Assert.assertEquals(20, cspInstanceSet.type.toList().top().intValue());
	}
	
	@Test
	@Ignore
	public void testClaim() throws Exception {
		InstanceSetI instanceSet = CSPInstanceSet.parse("(20 21 22)");
		Claim claim = new Claim(instanceSet, ForAllExists.getInstance(), 0.6, 0.6);
		double q = claim.getQuality();
		Assert.assertEquals(q, 0.6);
	}
	
	@Test
	public void testValid() throws ParseException {
		CSPInstance cspInstance = CSPInstance.parse("x1 x2 x3 (13 {1} x1 x2 x3)");
		CSPSolution cspSolutionInvalidIncomplete = CSPSolution.parse("[(x1->true) (x3->true)]");
		CSPSolution cspSolutionInvalidExtra = CSPSolution.parse("[(x1->true) (x2->true) (x3->true) (x4->true)]");
		CSPSolution cspSolutionValid = CSPSolution.parse("[(x1->true) (x2->true) (x3->true)]");
		CSPSolution cspSolutionValidMessedUpOrder = CSPSolution.parse("[ (x2->true) (x3->true) (x1->true)]");
		
		Assert.assertEquals(0d, cspInstance.valid(cspSolutionInvalidIncomplete,CSPConfig.getDefaultConfig())); // 1 = Solution is valid, 0= solution is invalid
		Assert.assertEquals(1d, cspInstance.valid(cspSolutionValid,CSPConfig.getDefaultConfig())); 
		Assert.assertEquals(0d, cspInstance.valid(cspSolutionInvalidExtra,CSPConfig.getDefaultConfig())); 
		Assert.assertEquals(1d, cspInstance.valid(cspSolutionValidMessedUpOrder,CSPConfig.getDefaultConfig())); 
	}
	
	@Test
	@Ignore
	// problem while calling quality!
	public void testQuality() throws ParseException {
		CSPInstance cspInstance = CSPInstance.parse("x1 x2 x3 (13 {1} x1 x2 x3)");
		CSPSolution cspSolutionValid = CSPSolution.parse("[(x1->true) (x2->true) (x3->true)]");
		Assert.assertEquals(0.897, cspInstance.quality(cspSolutionValid));
	}
	
	@Test
	public void testBelongsTo() throws ParseException {
		CSPInstance cspInstance = CSPInstance.parse("x1 x2 x3 (13 {1} x1 x2 x3)");
		CSPInstanceSet cspInstanceSet = CSPInstanceSet.parse("(13)");
		CSPInstanceSet cspInstanceSetWrong = CSPInstanceSet.parse("(523 768)");
		Option<String> instancebelongsSet = cspInstanceSet.belongsTo(cspInstance);
		Option<String> instancebelongsSetWrong = cspInstanceSetWrong.belongsTo(cspInstance);
		Assert.assertTrue(instancebelongsSet instanceof None<?>);
		Assert.assertTrue(instancebelongsSetWrong instanceof Some<?>);
	}
	
}
