package org.polarsys.chess.contracts.verificationService.test.runtime.tests;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.papyrus.junit.framework.classification.tests.AbstractPapyrusTest;
import org.eclipse.papyrus.junit.utils.rules.PluginResource;
import org.eclipse.papyrus.junit.utils.rules.ResourceSetFixture;
import org.eclipse.ui.IEditorPart;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.StateMachine;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;
import org.polarsys.chess.contracts.transformations.commands.CommandsCommon;
import org.polarsys.chess.contracts.transformations.commands.CommandsCommon.CommandEnum;
import org.polarsys.chess.contracts.transformations.main.GenerateFaultExtensions;
import org.polarsys.chess.diagram.ui.services.CHESSDiagramsGeneratorService;
import org.polarsys.chess.diagram.ui.services.ResultsGeneratorService;
import org.polarsys.chess.service.core.model.ChessSystemModel;
import org.polarsys.chess.service.core.model.UMLStateMachineModel;
import org.polarsys.chess.smvExporter.ui.services.CHESSSmvExporterService;

import eu.fbk.eclipse.standardTools.XSapExecService.services.XSapExecService;
import eu.fbk.eclipse.standardtools.ExecOcraCommands.ui.services.OCRAExecService;
import eu.fbk.eclipse.standardtools.ExecOcraCommands.ui.services.OCRAExecService.ValidationType;
import eu.fbk.eclipse.standardtools.ModelTranslatorToOcra.core.services.OSSTranslatorServiceAPI;
import eu.fbk.eclipse.standardtools.StateMachineTranslatorToSmv.core.services.SMVTranslatorServiceAPI;
import eu.fbk.eclipse.standardtools.diagram.DiagramDescriptor;
import eu.fbk.eclipse.standardtools.diagram.DocumentGenerator;
import eu.fbk.eclipse.standardtools.diagram.ui.docGenerators.DocumentGeneratorServiceFromOssModel;
import eu.fbk.eclipse.standardtools.nuXmvService.ui.services.NuXmvExecService;
import eu.fbk.eclipse.standardtools.utils.core.utils.StringArrayUtil;
import eu.fbk.tools.adapter.ui.preferences.PreferenceConstants;
import eu.fbk.tools.editor.oss.oss.OSS;

//@Headless
public class TestSafetyAnalysisOperations extends AbstractPapyrusTest {

	@Rule
	public ErrorCollector collector = new ErrorCollector();

	private final String configFileName = "configTest.properties";

	private String testOutput;
	private String testTempOutput;

	private EntityUtil entityUtil = EntityUtil.getInstance();
	private static final Logger logger = Logger.getLogger(TestSafetyAnalysisOperations.class);

	private final String projectFolderPath = "resources/SSR_fi/";
	private final String projectPath = projectFolderPath + "SSR.di";
	@Rule
	public final ResourceSetFixture resourceSetFixture = new ResourceSetFixture();

	private Class getSystemComponent() throws Exception {
		Model model = getModel();
		Package umlSelectedPackage = entityUtil.getSystemViewPackage(model);

		System.out.println("umlSelectedPackage: " + umlSelectedPackage);

		Class umlSelectedComponent = entityUtil.getSystemElement(model);
		return umlSelectedComponent;
	}

	@Test
	@PluginResource(projectPath)
	public void testFTA() throws Exception {

		// File ossFile = exportModelAsOssFile(testTempOutput);

		String oracleFolder = projectFolderPath + "/VandVResults/FTA";

		File outputFolder = new File(testOutput);
		String selectedDirectory = outputFolder.getAbsolutePath();
		String resultFilePath = selectedDirectory + File.separator + "result_contract_baset_fta.xml";
		System.out.println("resultFilePath: " + resultFilePath);
		// OCRAExecService ocraExecService =
		// OCRAExecService.getInstance(ChessSystemModel.getInstance());
		// ocraExecService.executeComputeFaultTree(ossFile, true,
		// resultFilePath, new NullProgressMonitor(), true);

		XSapExecService xSapExecService = XSapExecService.getInstance();

		File tempFolder = new File(testTempOutput);
		String selectedTempDirectory = tempFolder.getAbsolutePath();
		String extendedSmvFileName = selectedTempDirectory + File.separator + "extendedSmv.smv";
		String expandedFeiFileName = selectedTempDirectory + File.separator + "extendedFei.smv";
		String feiFileName = selectedTempDirectory + File.separator + "RootElement_System.fei";

		String fmsFileName = selectedTempDirectory + File.separator + "fms.xml";
		String ftaFmeaCond = "sensor1.sensed_speed_is_present=TRUE";

		Model model = getModel();
		//IEditorPart editor = TestBasicOperations.openEditor(model);
		Class umlSelectedComponent = getSystemComponent();

		String fileName = model.getName();
		String systemQN = umlSelectedComponent.getQualifiedName();
		List<String> args = new ArrayList<String>();
		args.add(systemQN);
		final String systemName = systemQN.substring(systemQN.lastIndexOf("::") + 2);
		args.add(systemName);
		String modelName = systemQN; // Used by the
		args.add(modelName);

		IFile umlFile = TestBasicOperations.getUmlFile(model);
		URI modelURI = URI.createPlatformResourceURI(umlFile.getFullPath().toString() , true);
	
		// Generate the monolithic SMV file
		File smvFile = TestBasicOperations.exportModelAsMonolithicSmvFile(selectedTempDirectory, umlSelectedComponent);
		String smvFileName = smvFile.getAbsolutePath();
		
		
		// Generate the FEI file
		GenerateFaultExtensions genFei = new GenerateFaultExtensions(modelURI, tempFolder, args);
		genFei.doGenerate(null);
	
		// Expand the FEI file
		xSapExecService.expandFaultExtensions(feiFileName, expandedFeiFileName, true);
		// Extend the SMV model
		xSapExecService.extendModel(smvFileName, expandedFeiFileName, fmsFileName, extendedSmvFileName, true);

		String ftFileName = selectedDirectory + File.separator + "ft.xml";

		xSapExecService.computeFt(extendedSmvFileName, fmsFileName, ftaFmeaCond, ftFileName, true);

		verifyDirsAreEqual(Paths.get(oracleFolder), Paths.get(selectedDirectory));
		verifyDirsAreEqual(Paths.get(selectedDirectory), Paths.get(oracleFolder));
	}

	@Test
	@PluginResource(projectPath)
	public void testFMEA() throws Exception {

		// File ossFile = exportModelAsOssFile(testTempOutput);

		String oracleFolder = projectFolderPath + "/VandVResults/FMEA";

		File outputFolder = new File(testOutput);
		String selectedDirectory = outputFolder.getAbsolutePath();
		String resultFilePath = selectedDirectory + File.separator + "result_fmea.xml";
		System.out.println("resultFilePath: " + resultFilePath);
		// OCRAExecService ocraExecService =
		// OCRAExecService.getInstance(ChessSystemModel.getInstance());
		// ocraExecService.executeComputeFaultTree(ossFile, true,
		// resultFilePath, new NullProgressMonitor(), true);

		XSapExecService xSapExecService = XSapExecService.getInstance();

		File tempFolder = new File(testTempOutput);
		String selectedTempDirectory = tempFolder.getAbsolutePath();
		String extendedSmvFileName = selectedTempDirectory + File.separator + "extendedSmv.smv";
		String expandedFeiFileName = selectedTempDirectory + File.separator + "extendedFei.smv";
		String feiFileName = selectedTempDirectory + File.separator + "RootElement_System.fei";

		String fmsFileName = selectedTempDirectory + File.separator + "fms.xml";
		String ftaFmeaCond = "sensor1.sensed_speed_is_present=TRUE";

		Model model = getModel();
		//IEditorPart editor = TestBasicOperations.openEditor(model);
		Class umlSelectedComponent = getSystemComponent();

		String fileName = model.getName();
		String systemQN = umlSelectedComponent.getQualifiedName();
		List<String> args = new ArrayList<String>();
		args.add(systemQN);
		final String systemName = systemQN.substring(systemQN.lastIndexOf("::") + 2);
		args.add(systemName);
		String modelName = systemQN; // Used by the
		args.add(modelName);

		IFile umlFile = TestBasicOperations.getUmlFile(model);
		URI modelURI = URI.createPlatformResourceURI(umlFile.getFullPath().toString() , true);
	
		// Generate the monolithic SMV file
		File smvFile = TestBasicOperations.exportModelAsMonolithicSmvFile(selectedTempDirectory, umlSelectedComponent);
		String smvFileName = smvFile.getAbsolutePath();
		
		
		// Generate the FEI file
		GenerateFaultExtensions genFei = new GenerateFaultExtensions(modelURI, tempFolder, args);
		genFei.doGenerate(null);
	
		// Expand the FEI file
		xSapExecService.expandFaultExtensions(feiFileName, expandedFeiFileName, true);
		// Extend the SMV model
		xSapExecService.extendModel(smvFileName, expandedFeiFileName, fmsFileName, extendedSmvFileName, true);

		String ftFileName = selectedDirectory + File.separator + "ft.xml";

		xSapExecService.computeFmea(extendedSmvFileName, fmsFileName, ftaFmeaCond, ftFileName, true);

		verifyDirsAreEqual(Paths.get(oracleFolder), Paths.get(selectedDirectory));
		verifyDirsAreEqual(Paths.get(selectedDirectory), Paths.get(oracleFolder));
	}
	
	@Test
	@PluginResource(projectPath)
	// @Ignore
	public void testContractBasedFTA() throws Exception {

		File ossFile = exportModelAsOssFile(testTempOutput);

		String oracleFolder = projectFolderPath + "/VandVResults/ContractBasedFTA";

		File outputFolder = new File(testOutput);
		String selectedDirectory = outputFolder.getAbsolutePath();
		String resultFilePath = selectedDirectory + File.separator + "result_contract_baset_fta.xml";
		System.out.println("resultFilePath: " + resultFilePath);
		OCRAExecService ocraExecService = OCRAExecService.getInstance(ChessSystemModel.getInstance());
		ocraExecService.executeComputeFaultTree(ossFile, true, resultFilePath, new NullProgressMonitor(), true);

		verifyDirsAreEqual(Paths.get(oracleFolder), Paths.get(selectedDirectory));
		verifyDirsAreEqual(Paths.get(selectedDirectory), Paths.get(oracleFolder));
	}

	private File exportModelAsOssFile(String outputFolder) throws Exception {
		IWorkspaceRoot wRoot = ResourcesPlugin.getWorkspace().getRoot();
		logger.debug("wRoot: " + wRoot);
		Class umlSelectedComponent = getSystemComponent();

		OSSTranslatorServiceAPI ossTranslatorServiceAPI = new OSSTranslatorServiceAPI(ChessSystemModel.getInstance());
		Object ocraModel = ossTranslatorServiceAPI.exportRootComponentToOssModel(umlSelectedComponent, true,
				new NullProgressMonitor());
		File tempFolder = new File(outputFolder);
		String selectedTempDirectory = tempFolder.getAbsolutePath();
		// String fileName =
		// toolToOCRAModelTranslator.getFileName(umlSelectedComponent);
		logger.debug("generateOssFileFromOssModel");
		String fileName = ossTranslatorServiceAPI.getFileName(umlSelectedComponent);
		File ossFile = ossTranslatorServiceAPI.exportOSSModelToOSSFile(ocraModel, fileName, selectedTempDirectory);
		return ossFile;
	}

	@Before
	public void setTestParameters() throws Exception {
		testOutput = cleanDirectory("testOutput");
		testTempOutput = cleanDirectory("testTempOutput");
		String OCRAFilePath = getConfigTestProperties().getProperty("OCRAFilePath");
		String nuXmvFilePath = getConfigTestProperties().getProperty("nuXmvFilePath");
		String xSapFilePath = getConfigTestProperties().getProperty("xSapFilePath");
		String feiFilePath = getConfigTestProperties().getProperty("feiFilePathPath");
		// String xSAPFilePath =
		// getConfigTestProperties().getProperty("xSAPFilePath");

		File testTempOutputFile = new File(testTempOutput);
		File ocraFile = new File(OCRAFilePath);
		File nuXmvFile = new File(nuXmvFilePath);
		File xSapFile = new File(xSapFilePath);
		File feiExpFile = new File(feiFilePath);

		eu.fbk.tools.adapter.ui.Activator.getDefault().getPreferenceStore().setValue(PreferenceConstants.TOOL_WORKSPACE,
				// "C:/Users/Alberto/Google Drive/AMASS
				// Project/ARTA_p1/eclipse/git_home/CHESS_FBK/plugins/contracts/org.polarsys.chess.contracts.verificationService.test.runtime/testTempOutput"
				testTempOutputFile.getAbsolutePath());

		eu.fbk.tools.adapter.ui.Activator.getDefault().getPreferenceStore().setValue(
				PreferenceConstants.OCRA_EXECUTABLE,
				// "C:/Users/Alberto/Google Drive/AMASS
				// Project/ARTA_p1/eclipse/git_home/CHESS_FBK/plugins/contracts/org.polarsys.chess.contracts.verificationService.test.runtime/resources/tools/ocra_win64.exe"
				ocraFile.getAbsolutePath());
		eu.fbk.tools.adapter.ui.Activator.getDefault().getPreferenceStore().setValue(
				PreferenceConstants.NUXMV_EXECUTABLE,
					nuXmvFile.getAbsolutePath());
		
		eu.fbk.tools.adapter.ui.Activator.getDefault().getPreferenceStore().setValue(
				PreferenceConstants.XSAP_EXECUTABLE,
					xSapFile.getAbsolutePath());

		eu.fbk.tools.adapter.ui.Activator.getDefault().getPreferenceStore().setValue(
				PreferenceConstants.FEI_EXPANDER_EXECUTABLE,
					feiExpFile.getAbsolutePath());
		
	}

	Model getModel() {
		return (Model) resourceSetFixture.getModel();
	}

	private void verifyDirsAreEqual(Path correctResultsDir, Path toCheckResultsDir) throws IOException {

		Files.walkFileTree(correctResultsDir, new SimpleFileVisitor<Path>() {
			@Override
			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
				FileVisitResult result = super.visitFile(file, attrs);

				// get the relative file name from path "one"
				Path correctFilePath = correctResultsDir.relativize(file);
				// construct the path for the counterpart file in "other"
				Path toCheckFilePath = toCheckResultsDir.resolve(correctFilePath);

				try {
					Assert.assertTrue(file + " is not equal to " + toCheckFilePath,
							compareTwoFilesIgnoreEOL(file, toCheckFilePath));
				} catch (Throwable t) {
					collector.addError(t);
				}

				return result;
			}
		});
	}

	private void verifyDirsHaveSameSize(Path correctResultsDir, Path toCheckResultsDir) throws IOException {
		Files.walkFileTree(correctResultsDir, new SimpleFileVisitor<Path>() {
			@Override
			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
				FileVisitResult result = super.visitFile(file, attrs);

				// get the relative file name from path "one"
				Path correctFilePath = correctResultsDir.relativize(file);
				// construct the path for the counterpart file in "other"
				Path toCheckFilePath = toCheckResultsDir.resolve(correctFilePath);

				try {
					Assert.assertTrue(file + " has not the same size of " + toCheckFilePath,
							sameSize(file, toCheckFilePath));
				} catch (Throwable t) {
					collector.addError(t);
				}

				return result;
			}
		});
	}

	private static String getFileSizeKiloBytes(File file) {
		return (double) file.length() / 1024 + "  kb";
	}

	private boolean sameSize(Path p1, Path p2) {

		String sizeFile1 = getFileSizeKiloBytes(p1.toFile());
		String sizeFile2 = getFileSizeKiloBytes(p2.toFile());

		return sizeFile1.equals(sizeFile2);
	}

	private static boolean compareTwoFilesIgnoreEOL(Path p1, Path p2) throws IOException {
		BufferedReader reader1 = new BufferedReader(new FileReader(p1.toFile()));
		BufferedReader reader2 = new BufferedReader(new FileReader(p2.toFile()));
		String line1 = reader1.readLine();
		String line2 = reader2.readLine();
		boolean areEqual = true;

		while (line1 != null || line2 != null) {
			if (line1 == null || line2 == null) {
				areEqual = false;
				break;
			} else if (!StringArrayUtil.equalsIgnoreNewlineStyle(line1, line2)) {
				areEqual = false;
				break;
			}
			line1 = reader1.readLine();
			line2 = reader2.readLine();
		}
		reader1.close();
		reader2.close();

		return areEqual;
	}

	private String cleanDirectory(String propertyDirectoryPathName) throws IOException {
		String workspaceDir = getConfigTestProperties().getProperty(propertyDirectoryPathName);
		File workspaceDirFile = new File(workspaceDir);
		FileUtils.deleteDirectory(workspaceDirFile);
		workspaceDirFile.mkdirs();
		return workspaceDir;
	}

	private Properties getConfigTestProperties() throws IOException {
		File configFile = new File(configFileName);

		FileReader reader = new FileReader(configFile);
		Properties props = new Properties();
		props.load(reader);
		reader.close();
		return props;

	}
}
