/*******************************************************************************
 * Copyright (C) 2020 Fondazione Bruno Kessler.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 ******************************************************************************/
package org.polarsys.chess.contracts.verificationService.test.runtime.tests;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.NotEnabledException;
import org.eclipse.core.commands.NotHandledException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.BasicEMap;
import org.eclipse.emf.common.util.EList;
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.junit.Before;
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.verificationService.test.runtime.util.TestResultsUtil;
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 eu.fbk.eclipse.standardtools.ExecOcraCommands.ui.services.OCRAExecService;
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.utils.core.utils.FileSystemUtil;
import eu.fbk.tools.adapter.ui.preferences.PreferenceConstants;
import eu.fbk.tools.editor.oss.oss.OSS;

public class TestBasicOperations extends AbstractPapyrusTest {

	@Rule
	public ErrorCollector collector = new ErrorCollector();

	private String testOutput;
	private String testTempOutput;

	private EntityUtil entityUtil = EntityUtil.getInstance();
	private static final Logger logger = Logger.getLogger(TestBasicOperations.class);

	private final String projectFolderPath = "resources/SSR_fi/";
	private final String projectPath = projectFolderPath + "SSR.di";
	
	private final String projectParamArchFolderPath = "resources/ParamArch/";
	private final String projectParamArchPath = projectParamArchFolderPath + "ParamArch.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 testExportStateMachinesAsMonolithicSmv() throws Exception {

		File outputFolder = new File(testOutput);
		String selectedDirectory = outputFolder.getAbsolutePath();

		File outputTempFolder = new File(testTempOutput);
		String selectedTempDirectory = outputTempFolder.getAbsolutePath();

		Class umlSelectedComponent = getSystemComponent();

		exportModelAsMonolithicSmvFile(selectedDirectory, selectedTempDirectory, umlSelectedComponent);

		String oracleFolder = projectFolderPath + "/MonolithicSmvFile";
		TestResultsUtil.dirsAreEqual(oracleFolder, selectedDirectory, collector);
	}

	@Test
	@PluginResource(projectParamArchPath)
	public void testInstantiateParameterizedAchitecture() throws Exception {
		File outputFolder = new File(testOutput);
		String selectedDirectory = outputFolder.getAbsolutePath();

		File outputTempFolder = new File(testTempOutput);
		String selectedTempDirectory = outputTempFolder.getAbsolutePath();

		Class umlSelectedComponent = getSystemComponent();
		String value = "4";
		
		File ossFile = TestBasicOperationsHeadless.exportModelAsOss(umlSelectedComponent, testTempOutput);
		String originalOssFileName = FilenameUtils.removeExtension(ossFile.getName());
		
		String resultFileName = originalOssFileName + "_instantiate.oss";
		instantiateParamArch(resultFileName, selectedDirectory, ossFile, value);
		
		String oracleFolder = projectParamArchFolderPath + "/InstantiationResults";
		TestResultsUtil.dirsAreEqual(oracleFolder, selectedDirectory, collector);
	}

	public static File instantiateParamArch(String resultFileName, String selectedDirectory, File ossFile, String value) throws Exception,
			NotDefinedException, ExecutionException, NotEnabledException, NotHandledException, FileNotFoundException {
		OCRAExecService ocraExecService = OCRAExecService.getInstance(ChessSystemModel.getInstance());

		boolean isDiscreteTime = false;
		String originalOssFileName = FilenameUtils.removeExtension(ossFile.getName());

		
		String paramListFilePath = selectedDirectory + File.separator + originalOssFileName + "_paramList.csv";

		ocraExecService.executeGetParameters(ossFile, paramListFilePath, true, new NullProgressMonitor());
		Map<String, String> parameterMap = ocraExecService.parseParametersFileAsMap(new File(paramListFilePath));

		EList<String> parametersList = new BasicEList<String>();

		
		for(String key : parameterMap.keySet()){
			parametersList.add(key+"="+value);
		}
		String assignedParamsFilePath = selectedDirectory + File.separator + originalOssFileName + "_assignedParams.csv";
	
		File parametersValuesFile = ocraExecService.createParameterValuesFile(parametersList, assignedParamsFilePath);

		String resultFilePath = selectedDirectory + File.separator + resultFileName;

		ocraExecService.executeInstantiateParamArch(ossFile, parametersValuesFile, isDiscreteTime, resultFilePath,
				new NullProgressMonitor());
		
		return new File(resultFilePath);
	}

	public static File exportModelAsMonolithicSmvFile(String selectedDirectory, String selectedTempDirectory,
			Class umlSelectedComponent) throws Exception, IOException {
		OSSTranslatorServiceAPI ossTranslatorServiceAPI = new OSSTranslatorServiceAPI(ChessSystemModel.getInstance());
		Object ocraModel = ossTranslatorServiceAPI.exportRootComponentToOssModel(umlSelectedComponent, true,
				new NullProgressMonitor());
		// String fileName =
		// toolToOCRAModelTranslator.getFileName(umlSelectedComponent);
		logger.debug("generateOssFileFromOssModel");
		String fileName = ossTranslatorServiceAPI.getFileName(umlSelectedComponent);
		File ossFile = ossTranslatorServiceAPI.exportOSSModelToOSSFile(ocraModel, fileName, selectedTempDirectory);

		File smvMapFile = createSmvMapFile(selectedTempDirectory, umlSelectedComponent);

		String outputFilePath = selectedDirectory + File.separator + umlSelectedComponent.getName().replace(".", "_")
				+ "_monolithic.smv";

		OCRAExecService ocraExecService = OCRAExecService.getInstance(ChessSystemModel.getInstance());
		ocraExecService.executePrintSystemImplementation(ossFile, smvMapFile, outputFilePath, true, true);

		return new File(outputFilePath);
	}

	public static File createSmvMapFile(String selectedDirectory, Class umlSelectedComponent)
			throws Exception, IOException {
		SMVTranslatorServiceAPI smvTranslatorServiceAPI = SMVTranslatorServiceAPI
				.getInstance(ChessSystemModel.getInstance(), UMLStateMachineModel.getInstance());
		HashMap<String, String> mapSmvFile_ComponentName = smvTranslatorServiceAPI
				.exportAllStateMachinesToSMVFiles(umlSelectedComponent, selectedDirectory, new NullProgressMonitor());

		File smvMapFile = FileSystemUtil.createSmvMapFile("map", selectedDirectory, mapSmvFile_ComponentName);
		return smvMapFile;
	}

	@Test
	@PluginResource(projectPath)
	public void testGenerationDocumentation() throws Exception {

		ChessSystemModel chessSystemModel = ChessSystemModel.getInstance();

		Model model = getModel();

		openEditor(model);

		OSSTranslatorServiceAPI ocraTranslatorService = OSSTranslatorServiceAPI.getInstance(chessSystemModel);

		Class umlSelectedComponent = getSystemComponent();
		Package activePackage = umlSelectedComponent.getNearestPackage();

		boolean isDiscreteTime = false;
		final OSS ossModel = ocraTranslatorService.exportRootComponentToOssModel(umlSelectedComponent, isDiscreteTime,
				new NullProgressMonitor());

		String imageExtension = ".svg";
		String currentProjectName = "SSR";
		String docFormat = "html";

		CHESSDiagramsGeneratorService chessDiagramsGeneratorService = CHESSDiagramsGeneratorService.getInstance();

		Collection<Diagram> chessDiagrams = chessDiagramsGeneratorService.getDiagrams();

		System.out.println("num diagrams: " + chessDiagrams.size());

		DocumentGeneratorServiceFromOssModel documentGeneratorService = new DocumentGeneratorServiceFromOssModel(
				ossModel, chessSystemModel, activePackage);
		documentGeneratorService.setParametersBeforeDocumentGeneration(testOutput, imageExtension, true, true, true,
				true, true, true, true, true, true, true, true, true, true, true, true);

		final DocumentGenerator documentGenerator = documentGeneratorService.createDocumentFile(currentProjectName,
				docFormat, ossModel.getSystem(), new NullProgressMonitor());

		documentGeneratorService.addLocalAttributeDescriptors(umlSelectedComponent, documentGenerator);

		System.out.println("resultsGeneratorService");

		final ResultsGeneratorService resultsGeneratorService = new ResultsGeneratorService();
		resultsGeneratorService.setParametersBeforeDocumentGeneration(testOutput, true, imageExtension);
		resultsGeneratorService.addResultsDescriptors(umlSelectedComponent, activePackage, documentGenerator);

		chessDiagramsGeneratorService.setParametersBeforeDiagramsGenerator(testOutput, imageExtension);
		System.out.println("diagramDescriptors");
		Set<DiagramDescriptor> diagramDescriptors = new HashSet<DiagramDescriptor>();
		for (Diagram diagram : chessDiagrams) {
			DiagramDescriptor dd = chessDiagramsGeneratorService.createDiagramWithDescriptor(diagram, null,
					new NullProgressMonitor());
			if (dd != null) {
				diagramDescriptors.add(dd);
			}
		}
		documentGeneratorService.addDiagramDescriptors(diagramDescriptors, documentGenerator);
		documentGenerator.generate(testOutput);

		String oracleFolder = projectFolderPath + "/Documentation";

		File outputFolder = new File(testOutput);
		String selectedDirectory = outputFolder.getAbsolutePath();

		TestResultsUtil.dirsHaveSameSize(oracleFolder, selectedDirectory, collector);

	}

	public static IEditorPart openEditor(final Model model) throws Exception {
		IFile iFile = getUmlFile(model);
		return EntityUtil.getInstance().openCurrentModelIntoEditor(iFile);
	}

	public static IFile getUmlFile(final Model model) {
		final org.eclipse.emf.ecore.resource.Resource resource = model.eResource();

		URI resourceURI = resource.getURI();
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IPath workspacePath = workspace.getRoot().getLocation();
		IPath finalPath = workspacePath.append(resourceURI.toPlatformString(false));
		@SuppressWarnings("deprecation")
		final IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(finalPath);

		// System.out.println("location: "+location);
		IFile iFile = files[0];
		return iFile;
	}

	@Before
	public void setTestParameters() throws Exception {
		testOutput = TestResultsUtil.cleanDirectory("testOutputBasicOperations");
		testTempOutput = TestResultsUtil.cleanDirectory("testTempOutput");
		String OCRAFilePath = TestResultsUtil.getProperty("OCRAFilePath");
		String nuXmvFilePath = TestResultsUtil.getProperty("nuXmvFilePath");

		File testTempOutputFile = new File(testTempOutput);
		File ocraFile = new File(OCRAFilePath);
		File nuXmvFile = new File(nuXmvFilePath);

		eu.fbk.tools.adapter.ui.Activator.getDefault().getPreferenceStore().setValue(PreferenceConstants.TOOL_WORKSPACE,
				testTempOutputFile.getAbsolutePath());

		eu.fbk.tools.adapter.ui.Activator.getDefault().getPreferenceStore()
				.setValue(PreferenceConstants.OCRA_EXECUTABLE, 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.OSLC_ENABLED, false);
	}

	Model getModel() {
		return (Model) resourceSetFixture.getModel();
	}

}
