import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;

public class TestCastTester {

	public static Properties config = new Properties();
	private ArrayList<T3ScriptFile> files = new ArrayList<T3ScriptFile>();
	private int startIteration = 0;
	private ArrayList<String> exclusionList;
	
	// -----------------------------------------------------------------------------------------------

	public TestCastTester() {
	}

	// -----------------------------------------------------------------------------------------------

	public void run() {
		System.out.println("STF475 TestCast Tester v0.2");
		try {
			FileUtils.loadConfig(config);
		} catch (IOException e) {
			System.err
					.println("[ERROR] Cannot load config file or config file is incomplete.");
			return;
		}

		String atsPath = config.get("ATSPath").toString();
		System.out.println("Gathering files...");
		FileUtils.visitAllFiles(new File(atsPath), files);

		System.out.println("Reading exclusion list...");
		exclusionList = FileUtils.readExclusionList(new File("resources/skipList.txt"));
		
		File allLogFile = new File(config.get("LogPath") + "/all.log");
		File criticalLogFile = new File(config.get("LogPath") + "/critical.log");
		Logger logger = new Logger(allLogFile, criticalLogFile);
		logger.init();
		
		for (int i=0; i < files.size(); i++) {
			if (startIteration > i)
				continue;
			File srcFile = files.get(i).getT3File();
			String t3FileName = srcFile.getName();
			File tempFile = new File(config.get("TempPath") + "/" + t3FileName);
	
			if (inExclusionList(t3FileName)) {
				System.out.println("**exclusion list match. skipping " + t3FileName);
				continue;
			} 
			
			try {
				FileUtils.copyFile(new File(srcFile.getAbsolutePath()), tempFile);
			} catch (IOException e) {
				System.err.println("[ERROR] Could not copy file " + srcFile.getAbsolutePath() + "! Stopping tester...");
				return;
			}
			
			int moduleCount = FileUtils.countT3Modules(tempFile);
			
			ArrayList<File> filesToProcess = new ArrayList<File>();
			if (moduleCount > 1) {
				filesToProcess.addAll(FileUtils.splitT3ModuleFiles(tempFile));
			} else {
				filesToProcess.add(tempFile);
			}

			if (filesToProcess.size() <= 0)
				continue;
			
			ArrayList<File> xsdFiles = files.get(i).getXsdFiles();
			if (xsdFiles != null) {
				for(File xsdFile : xsdFiles) {
					File tempXsdFile = new File(config.get("TempPath") + "/" + xsdFile.getName());
					try {
						FileUtils.copyFile(new File(xsdFile.getAbsolutePath()), tempXsdFile);
					} catch (IOException e) {
						System.err.println("[ERROR] Could not copy file " + xsdFile.getAbsolutePath() + "! Stopping tester...");
						return;
					}
					filesToProcess.add(tempXsdFile);
				}
			}
			
			srcFile = files.get(i).getXmlFile();
			if (srcFile != null) {
				String xmlFileName = srcFile.getName();
				tempFile = new File(config.get("TempPath") + "/" + xmlFileName);
				
				try {
					FileUtils.copyFile(new File(srcFile.getAbsolutePath()), tempFile);
				} catch (IOException e) {
					System.err.println("[ERROR] Could not copy file " + srcFile.getAbsolutePath() + "! Stopping tester...");
					return;
				}
			}
			
			T3ExpectedOutput expectedOutput = FileUtils.extractExpectedOutput(filesToProcess.get(0));

			TestCastProjectBuilder builder = new TestCastProjectBuilder();
			for (int j=0; j < filesToProcess.size(); j++) {
				builder.addFile(filesToProcess.get(j).getAbsolutePath());
			}
			builder.setSUT(new File(config.get("LoopbackAdapterPath").toString()).getAbsolutePath());
			File projectFile = new File(config.get("TempPath") + "/testcast.tcproj");
			builder.saveProjectFile(projectFile);

			TestCastRunner runner = new TestCastRunner(projectFile, filesToProcess.get(0).getName().substring(0, filesToProcess.get(0).getName().indexOf(".ttcn")), logger, i+1);
			runner.run();
			runner.evaluateResults(expectedOutput);
						
			// cleanup
			if (tempFile.exists()) {
				boolean success = tempFile.delete();
				if (!success)
					System.err.println("[ERROR] Could not delete file " + tempFile.getAbsolutePath());
			}
			for (int j=0; j < filesToProcess.size(); j++) {
				if (filesToProcess.get(j).exists()) {
					boolean success = filesToProcess.get(j).delete();
					if (!success)
						System.err.println("[ERROR] Could not delete file " + tempFile.getAbsolutePath());
				}
			}
			if (projectFile.exists()) {
				boolean success = projectFile.delete();
				if (!success)
					System.err.println("[ERROR] Could not delete file " + tempFile.getAbsolutePath());
			}
		}
		System.out.println("done.");
		logger.finish();
	}

	// -----------------------------------------------------------------------------------------------

	private boolean inExclusionList(String filename) {
		for (int i=0; i < exclusionList.size(); i++) {
			if (filename.contains(exclusionList.get(i)))
				return true;
		}
		return false;
	}

	// -----------------------------------------------------------------------------------------------

	public static void main(String[] args) {
		new TestCastTester().run();
	}

}
