package org.momut.ooas.test.utils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.junit.Assert;
import org.momut.ooas.Compiler;
import org.momut.ooas.Compiler.ILogCallBack;
import org.momut.ooas.CompilerConfiguration.Backend;



/**
 * Base class for MoMuT Test classes
 * @author DemetzM
 * @author KrennW
 *
 */
public abstract class OoasTest {
	/// static stuff
	private static final String  s_COMPILER_TEMP_DIR = "ooasComp.temp.dir";
	private static final String  s_tempDir        = System.getProperty(OoasTest.s_COMPILER_TEMP_DIR);
	private static final boolean s_hasTempDir     = s_tempDir != null && !s_tempDir.isEmpty();

	protected static final String s_modelsDir = "org/momut/ooas/test/models";
	protected static final String s_standardDir = s_modelsDir + "/standard/";
	protected static final String s_complexDir = s_modelsDir + "/complex/";

	protected static File createTempDirectory(String dirName) throws IOException {
		return Files.createTempDirectory(dirName).toFile();
	}

	protected static File createTempDirectory(String prefix, String directoryName) throws IOException {
		final File file = new File(prefix);
		if (!file.exists())
			file.mkdirs();

		return Files.createTempDirectory(Paths.get(prefix), directoryName).toFile();
	}


	/**
	 * Creates an temporary directory either in the system's default
	 * temp directory or in the directory specified via the "momut.temp.dir"
	 * environment variable.
	 * @param clazz A class. Used to name the directory: "MoMuT_" + clazz.getSimpleName()
	 * @return file object pointing to the newly created temp. dir.
	 * @throws IOException
	 */
	protected static File createOutputDirectory(Class<?> clazz) throws IOException {
		final String dirName = "MoMuT_" + clazz.getSimpleName() + "_";
		if (s_hasTempDir)
			return createTempDirectory(s_tempDir, dirName);
		return createTempDirectory(dirName);
	}


	/// instance stuff
	public final String m_testName;
	public final String m_model;


	public OoasTest(String testName, String model) {
		m_testName = testName;
		m_model = model;
	}


	/** Run the OOAS Compiler and check whether there were any errors during compilation.
	 * @param outputDir
	 * @throws IOException */
	private static void runOoasCompiler(String testName, File ooasFile, Backend backend, File outputDir) throws IOException {
		final byte[] ooasInput = Files.readAllBytes(ooasFile.toPath());// ooasCode.getBytes("UTF-8");
		final FileOutputStream compilerFileOutput = new FileOutputStream(new File(outputDir, String.format("%s.compiler", testName.replace("/", "."))));
		final Compiler compiler = new Compiler(
				testName,
				new ByteArrayInputStream(ooasInput),
				compilerFileOutput,
				backend);
		final int errors = compiler.compile( new ILogCallBack(){
			@Override
			public void logError(boolean toConsole, String message) {
				System.out.println(message);
			}} );
		compilerFileOutput.flush();
		compilerFileOutput.close();
		if (errors != 0) {
			System.out.println("##Faulty OOAS produced for " + testName);
		}
		Assert.assertEquals(
				String.format("Errors during ooas compiler run: %s", compiler.toString()),
				0,
				errors);
	}

	public static void runOoasCompiler(String testName, File ooasFile, File outputDir, Backend backend) throws IOException {
		runOoasCompiler(testName, ooasFile, backend, outputDir);
	}

}
