package pointers;

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

import java.io.File;
import java.io.IOException;

import org.junit.Test;

import config.Example;
import edu.udel.cis.vsl.tass.config.VerifyConfiguration;
import edu.udel.cis.vsl.tass.front.minimp.ModelExtractor;
import edu.udel.cis.vsl.tass.model.IF.ModelIF;
import edu.udel.cis.vsl.tass.util.SyntaxException;
import edu.udel.cis.vsl.tass.verify.Verification;

public class PointerTest {
	private File rootDirectory = new File(Example.exampleDirectory, "pointers");
	private File repository = new File(rootDirectory, "TASSREP");

	@Test
	public void simplePointerTest() throws IOException, SyntaxException {
		VerifyConfiguration config1 = new VerifyConfiguration(repository);
		ModelIF model1;

		config1.setSourceFile(new File(rootDirectory, "simplePointer.c"));
		config1.setModelName("simplePointer");
		config1.setNumProcs(1);
		model1 = ModelExtractor.extractModel(config1);
		assertTrue(Verification.verify(model1, config1, true));
	}

	@Test
	public void simpleAllocateTest() throws IOException, SyntaxException {
		VerifyConfiguration config2 = new VerifyConfiguration(repository);
		ModelIF model2;

		config2.setSourceFile(new File(rootDirectory, "simpleAllocate.c"));
		config2.setModelName("simpleAllocate");
		config2.setNumProcs(1);
		model2 = ModelExtractor.extractModel(config2);
		assertTrue(Verification.verify(model2, config2, true));
	}

	@Test
	public void simpleRecordTest() throws IOException, SyntaxException {
		VerifyConfiguration config3 = new VerifyConfiguration(repository);
		ModelIF model3;

		config3.setSourceFile(new File(rootDirectory, "simpleRecord.c"));
		config3.setModelName("simpleRecord");
		config3.setNumProcs(1);
		model3 = ModelExtractor.extractModel(config3);
		assertTrue(Verification.verify(model3, config3, true));
	}

	@Test
	public void pointerAdditionTest() throws IOException, SyntaxException {
		VerifyConfiguration config = new VerifyConfiguration(repository);
		ModelIF model;

		config.setSourceFile(new File(rootDirectory, "pointerAddition.c"));
		config.setModelName("pointerAddition");
		config.setNumProcs(1);
		model = ModelExtractor.extractModel(config);
		assertTrue(Verification.verify(model, config, true));
	}

	@Test
	public void freeTest() throws IOException, SyntaxException {
		VerifyConfiguration config = new VerifyConfiguration(repository);
		ModelIF model;

		config.setSourceFile(new File(rootDirectory, "free.c"));
		config.setModelName("free");
		config.setNumProcs(1);
		config.setInput("n", 10);
		model = ModelExtractor.extractModel(config);
		assertTrue(Verification.verify(model, config, true));
	}
	
	@Test
	public void freeAdditionTest() throws IOException, SyntaxException {
		VerifyConfiguration config = new VerifyConfiguration(repository);
		ModelIF model;

		config.setSourceFile(new File(rootDirectory, "freeAddition.c"));
		config.setModelName("freeAddition");
		config.setNumProcs(1);
		config.setInput("n", 10);
		model = ModelExtractor.extractModel(config);
		assertTrue(Verification.verify(model, config, true));
	}

	@Test
	public void leakTest() throws IOException, SyntaxException {
		VerifyConfiguration config = new VerifyConfiguration(repository);
		ModelIF model;

		config.setSourceFile(new File(rootDirectory, "leak.c"));
		config.setModelName("leak");
		config.setNumProcs(1);
		config.setErrorBound(10);
		model = ModelExtractor.extractModel(config);
		assertFalse(Verification.verify(model, config, true));
	}

	@Test
	public void arrowOperatorTest() throws IOException, SyntaxException {
		VerifyConfiguration config = new VerifyConfiguration(repository);
		ModelIF model;
		config.setSourceFile(new File(rootDirectory, "arrowOperator.c"));
		config.setModelName("free");
		config.setNumProcs(1);
		model = ModelExtractor.extractModel(config);

		assertTrue(Verification.verify(model, config, true));
	}
	
	@Test
	public void pointerCastTest() throws IOException, SyntaxException {
		VerifyConfiguration config = new VerifyConfiguration(repository);
		ModelIF model;
		config.setSourceFile(new File(rootDirectory, "pointerCast.c"));
		config.setModelName("pointerCast");
		config.setNumProcs(1);
		model = ModelExtractor.extractModel(config);

		assertTrue(Verification.verify(model, config, true));
	}
	
	@Test
	public void freeBad() throws IOException, SyntaxException {
		VerifyConfiguration config = new VerifyConfiguration(repository);
		ModelIF model;
		config.setSourceFile(new File(rootDirectory, "freeBad.c"));
		config.setModelName("freeBad");
		config.setNumProcs(1);
		config.setErrorBound(10);
		model = ModelExtractor.extractModel(config);

		assertFalse(Verification.verify(model, config, true));
	}
	
	@Test
	public void freeTwice() throws IOException, SyntaxException {
		VerifyConfiguration config = new VerifyConfiguration(repository);
		ModelIF model;
		config.setSourceFile(new File(rootDirectory, "freeTwice.c"));
		config.setModelName("freeTwice");
		config.setNumProcs(1);
		config.setErrorBound(10);
		model = ModelExtractor.extractModel(config);

		assertFalse(Verification.verify(model, config, true));
	}
	
	@Test
	public void voidCast() throws IOException, SyntaxException {
		VerifyConfiguration config = new VerifyConfiguration(repository);
		ModelIF model;
		config.setSourceFile(new File(rootDirectory, "voidCast.c"));
		config.setModelName("voidCast");
		config.setNumProcs(1);
		model = ModelExtractor.extractModel(config);

		assertTrue(Verification.verify(model, config, true));
	}
	
}
