package csp;

import java.util.Iterator;

import junit.framework.Assert;

import org.junit.Test;

import scg.Claim;
import scg.Config;
import scg.OpposeAction;
import scg.ParseException;
import scg.SolveRequest;
import edu.neu.ccs.demeterf.lib.Empty;
import edu.neu.ccs.demeterf.lib.List;
import edu.neu.ccs.demeterf.lib.Some;


public class TestCSPAvatar {
	
	@Test
	public void testSolve() throws scg.ParseException, ParseException, csp.ParseException {
		Config cfg = CSPConfig.getDefaultConfig();
		csp.avatar.CSPAvatar avatar = new csp.avatar.CSPAvatar(cfg);
		String inpt = "x1 x2 x3  (12 {1} x1 x2 x3 ) ";
		CSPInstance instance = CSPInstance.parse(inpt);
		Assert.assertEquals(inpt, instance.print());
		
		
		//// reto please see here.
		
		String inpt2 = "csp.CSPInstanceSet {{ (12 22) }} scg.protocol.PositiveSecret {{     }} 0.444444 0.8";
		Claim claim = Claim.parse(inpt2);
		Assert.assertEquals(inpt2, claim.print());
		SolveRequest req = new SolveRequest(instance, new Some<Claim>(claim));
		CSPSolution solution = (CSPSolution) avatar.solve(req);
		
		int elementNumber = solution.getAssign().size();
		Assert.assertEquals(3, elementNumber);
	}
	
	@Test
	public void testValidQuality() throws ParseException {
		Claim claim1 = Claim.parse("csp.CSPInstanceSet {{ (12 22) }} scg.protocol.PositiveSecret {{ }} 0.99 0.8");
		Assert.assertEquals(0.99, claim1.getQuality());
		Config conf = Config.parse("scg_config[domain: csp.CSPDomain protocols: positiveStandard tournamentStyle: full round-robin " +
				"turnDuration: 60 maxNumAvatars: 20 minStrengthening: 0.01 initialReputation: 100.0 " +
				"maxReputation: 1000.0 reputationFactor: 0.4 minProposals: 2 maxProposals: 5 numRounds: 9 proposedClaimMustBeNew: true minConfidence: 0.1] csp.CSPConfig {{ csp_config[maxRelNum: 255 maxVariables: 10 ] }}");
		
		//no error
		Assert.assertFalse(((CSPInstanceSet) claim1.getInstanceSet()).valid(conf).isSome());
		
		Claim claim2 = Claim.parse("csp.CSPInstanceSet {{ (12 22) }} scg.protocol.PositiveSecret {{ }} 1.0 0.8");
		Assert.assertEquals(1.0, claim2.getQuality());

		//no error
		Assert.assertFalse(((CSPInstanceSet) claim2.getInstanceSet()).valid(conf).isSome());
		
		Claim claim3 = Claim.parse("csp.CSPInstanceSet {{ (12 800) }} scg.protocol.PositiveSecret {{ }} 1.1 0.8");
		Assert.assertEquals(1.1, claim3.getQuality());
		//TODO error, quality is bigger than 1
		Assert.assertTrue(((CSPInstanceSet) claim3.getInstanceSet()).valid(conf).isSome());
	}
		
	
	@Test
	public void testPropose() {
		Config cfg = CSPConfig.getDefaultConfig();
		csp.avatar.CSPAvatar avatar = new csp.avatar.CSPAvatar(cfg);
		
		List<Claim> response = avatar.propose(new Empty<Claim>());
		for(Iterator<Claim> claims = response.iterator(); claims.hasNext();){
			Claim claim = claims.next();
			CSPInstanceSet set = (CSPInstanceSet) claim.getInstanceSet();
			
			for (Iterator<Integer> ints =set.type.iterator(); ints.hasNext();) {
				int result = ints.next();		
				boolean numberInRange = result <= 255 && result >= 0;
				Assert.assertTrue(numberInRange);
			}
			Assert.assertEquals(2, set.type.size());
		}
		Assert.assertEquals(5, response.length());
	}

	@Test
	public void testProvide() throws ParseException {
		Config cfg = CSPConfig.getDefaultConfig();
		csp.avatar.CSPAvatar avatar = new csp.avatar.CSPAvatar(cfg);
		
		Claim claim = Claim.parse("csp.CSPInstanceSet {{ (20 21 22) }} scg.protocol.PositiveSecret {{ }} 0.444444 0.9");
		CSPInstance response = (CSPInstance) avatar.provide(claim);
		System.out.println("provide from avatar: " + (response.print()));
		
		Assert.assertEquals(360, response.clauses.length());
		
		List<Var> varlistInRes = response.vars;
		
		for (Iterator<Clause> clauses = response.clauses.iterator(); clauses.hasNext();) {
			
			Clause c = clauses.next();
		
			for (Iterator<Var> vars = c.vars.iterator(); vars.hasNext();) {				
				Var v = vars.next();			
				Assert.assertTrue(varlistInRes.contains(v));				
			}
		}	
	}
	
	@Test
	public void testOppose() throws ParseException {
		Config cfg = CSPConfig.getDefaultConfig();
		csp.avatar.CSPAvatar avatar = new csp.avatar.CSPAvatar(cfg);
		
		Claim claim = Claim.parse("csp.CSPInstanceSet {{ (20 21 22) }} scg.protocol.PositiveSecret {{ }} 0.444444 0.8");
		List<Claim> claims = List.create();
		claims = claims.append(claim);
		List<OpposeAction> response = avatar.oppose(claims);
		for(Iterator<OpposeAction> oppActionsIterator = response.iterator(); oppActionsIterator.hasNext();){
			OpposeAction oppAction = oppActionsIterator.next();
			System.out.println("oppose from avatar: " + oppAction.getClass()); 
		}
		
		
	}
	
}
