package pl.edu.pw.mini.jk.mixeduct.attacker;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.apache.commons.math3.random.RandomGenerator;
import org.apache.commons.math3.random.Well19937c;
import org.apache.commons.math3.util.Pair;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Answers;

import com.google.common.collect.ImmutableList;

import junit.framework.TestCase;
import pl.edu.pw.mini.jk.sg.mixeduct.IterationResult;
import pl.edu.pw.mini.jk.sg.mixeduct.attacker.AttackerStrategy;
import pl.edu.pw.mini.jk.sg.mixeduct.attacker.ProbabilisticStrategyAttackerWithHistoryFactory;
import pl.edu.pw.mini.jk.sg.mixeduct.attacker.historychanger.ConstantAttackerHistory;

public class ProbabilisticStrategyAttackerWithHistoryFactoryTest {
    private RandomGenerator rng = new Well19937c();
    
    @SuppressWarnings("unchecked")
    @Test
    public void historyPurgeTest() {
        ProbabilisticStrategyAttackerWithHistoryFactory<Integer> factory = new ProbabilisticStrategyAttackerWithHistoryFactory<Integer>(ImmutableList.of(new Pair<>(ImmutableList.of(5), 1.)),														 2, rng, ConstantAttackerHistory.instance());
        AttackerStrategy<Integer> a1 = factory.getInstance();

        TestCase.assertEquals(1, a1.getPmf().size());

	final IterationResult<?,Integer,?,?,?> ir1 = mock(IterationResult.class, Answers.RETURNS_DEEP_STUBS);
	when(ir1.attackerStrategy().strategyAsPairs()).thenReturn(ImmutableList.of(new Pair<>(ImmutableList.<Integer>of(2), 1.)));
	factory.registerIterationResult(1, ir1, a1);
        AttackerStrategy<Integer> a2 = factory.getInstance();

	TestCase.assertEquals(2, a2.getPmf().size());
        Assert.assertThat(
                a2.getPmf(),
                CoreMatchers.hasItems(new Pair[] { new Pair<ImmutableList<Integer>, Double>(ImmutableList.of(5), 0.5),
                        new Pair<ImmutableList<Integer>, Double>(ImmutableList.of(2), 0.5) }));

	final IterationResult<?,Integer,?,?,?> ir2 = mock(IterationResult.class, Answers.RETURNS_DEEP_STUBS);
	when(ir2.attackerStrategy().strategyAsPairs()).thenReturn(ImmutableList.of(new Pair<>(ImmutableList.<Integer>of(2), 1.)));
	factory.registerIterationResult(2, ir2, a2);

	AttackerStrategy<Integer> a3 = factory.getInstance();
	
        TestCase.assertEquals(1, a3.getPmf().size());
        Assert.assertThat(a3.getPmf(),
                 CoreMatchers.hasItem(new Pair<ImmutableList<Integer>, Double>(ImmutableList.of(2), 1.)));
    }

}
