package simpleMP;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileNotFoundException;

import org.junit.BeforeClass;
import org.junit.Test;

import config.Example;
import edu.udel.cis.vsl.tass.config.CompareConfiguration;
import edu.udel.cis.vsl.tass.config.VerifyConfiguration;
import edu.udel.cis.vsl.tass.config.RunConfiguration.DeadlockStrategy;
import edu.udel.cis.vsl.tass.config.RunConfiguration.ReductionStrategy;
import edu.udel.cis.vsl.tass.front.minimp.ModelExtractor;
import edu.udel.cis.vsl.tass.front.minimp.ModelPair;
import edu.udel.cis.vsl.tass.model.IF.ModelIF;
import edu.udel.cis.vsl.tass.verify.Comparison;
import edu.udel.cis.vsl.tass.verify.Verification;

public class SimpleMPTest {
	private static ModelIF specModel, implModel, typeModel, bufferModel;
	private static CompareConfiguration compareConfiguration;
	private static VerifyConfiguration specConfiguration, implConfiguration,
			typeConfiguration, bufferConfiguration;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		ModelPair pair;
		File rootDirectory = new File(Example.exampleDirectory, "simpleMP");

		compareConfiguration = new CompareConfiguration(new File(rootDirectory,
				"TASSREP"));
		compareConfiguration.setSimplify(false);
		compareConfiguration.setSpecSourceFile(new File(rootDirectory,
				"simpleMPSpec.c"));
		compareConfiguration.setImplSourceFile(new File(rootDirectory,
				"simpleMPImplGood.c"));
		compareConfiguration.setSpecNumProcs(2);
		compareConfiguration.setImplNumProcs(2);
		compareConfiguration.setSpecModelName("simpleMPSpec");
		compareConfiguration.setImplModelName("simpleMPImplGood");
		specConfiguration = compareConfiguration.specConfiguration();
		implConfiguration = compareConfiguration.implConfiguration();
		pair = ModelExtractor.extractModelPair(compareConfiguration);
		typeConfiguration = new VerifyConfiguration(new File(rootDirectory,
				"TASSREP"));
		typeConfiguration.setSourceFile(new File(rootDirectory,
				"simpleMPTypeBad.c"));
		typeConfiguration.setNumProcs(2);
		typeConfiguration.setModelName("simpleMPTypeBad");
		bufferConfiguration = new VerifyConfiguration(new File(rootDirectory,
				"TASSREP"));
		bufferConfiguration.setSourceFile(new File(rootDirectory,
				"simpleMPBufferBad.c"));
		bufferConfiguration.setNumProcs(2);
		bufferConfiguration.setModelName("simpleMPTypeBad");
		specModel = pair.spec();
		implModel = pair.impl();
		typeModel = ModelExtractor.extractModel(typeConfiguration);
		bufferModel = ModelExtractor.extractModel(bufferConfiguration);
	}

	@Test
	public void testVerifySpec() throws FileNotFoundException {
		assertTrue(Verification.verify(specModel, specConfiguration, true));
	}

	@Test
	public void testVerifyImpl() throws FileNotFoundException {
		assertTrue(Verification.verify(implModel, implConfiguration, true));
	}

	@Test
	public void testVerifyImplUrgent() throws FileNotFoundException {
		VerifyConfiguration config = new VerifyConfiguration(implConfiguration);

		config.setReductionStrategy(ReductionStrategy.URGENT);
		assertTrue(Verification.verify(implModel, config, true));
	}

	@Test
	public void testVerifyImplSimplify() throws FileNotFoundException {
		VerifyConfiguration config = new VerifyConfiguration(implConfiguration);

		config.setSimplify(true);
		assertTrue(Verification.verify(implModel, config, true));
	}

	@Test
	public void testVerifyImplSimplifyUrgent() throws FileNotFoundException {
		VerifyConfiguration config = new VerifyConfiguration(implConfiguration);

		config.setSimplify(true);
		config.setReductionStrategy(ReductionStrategy.URGENT);
		assertTrue(Verification.verify(implModel, config, true));
	}

	@Test
	public void testCompare() throws FileNotFoundException {
		assertTrue(Comparison.compare(specModel, implModel,
				compareConfiguration, true));
	}

	@Test
	public void testCompareUrgent() throws FileNotFoundException {
		CompareConfiguration config = new CompareConfiguration(
				compareConfiguration);

		config.setReductionStrategy(ReductionStrategy.URGENT);
		assertTrue(Comparison.compare(specModel, implModel, config, true));
	}

	@Test
	public void testComparePotential() throws FileNotFoundException {
		CompareConfiguration config = new CompareConfiguration(
				compareConfiguration);

		config.setDeadlockStrategy(DeadlockStrategy.POTENTIAL);
		assertTrue(Comparison.compare(specModel, implModel, config, true));
	}

	@Test
	public void testComparePotentialSimplify() throws FileNotFoundException {
		CompareConfiguration config = new CompareConfiguration(
				compareConfiguration);

		config.setDeadlockStrategy(DeadlockStrategy.POTENTIAL);
		config.setSimplify(true);
		assertTrue(Comparison.compare(specModel, implModel, config, true));
	}

	@Test
	public void testCompareIgnore() throws FileNotFoundException {
		CompareConfiguration config = new CompareConfiguration(
				compareConfiguration);

		config.setDeadlockStrategy(DeadlockStrategy.IGNORE);
		assertTrue(Comparison.compare(specModel, implModel, config, true));
	}

	@Test
	public void testVerifyTypeBad() throws FileNotFoundException {
		assertFalse(Verification.verify(typeModel, typeConfiguration, true));
	}

	@Test
	public void testVerifyBufferBad() throws FileNotFoundException {
		assertFalse(Verification.verify(bufferModel, bufferConfiguration, true));
	}
}
