/*********************************************************************
* Copyright (c) 2008 The University of York.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.epsilon.emc.simulink.model;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Future;

import org.eclipse.epsilon.common.util.Multimap;
import org.eclipse.epsilon.common.util.StringProperties;
import org.eclipse.epsilon.emc.simulink.engine.MatlabEngine;
import org.eclipse.epsilon.emc.simulink.engine.MatlabEnginePool;
import org.eclipse.epsilon.emc.simulink.exception.MatlabException;
import org.eclipse.epsilon.emc.simulink.exception.MatlabRuntimeException;
import org.eclipse.epsilon.emc.simulink.introspection.java.SimulinkPropertyGetter;
import org.eclipse.epsilon.emc.simulink.introspection.java.SimulinkPropertySetter;
import org.eclipse.epsilon.emc.simulink.model.TypeHelper.Kind;
import org.eclipse.epsilon.emc.simulink.model.element.ISimulinkModelElement;
import org.eclipse.epsilon.emc.simulink.model.element.SimulinkBlock;
import org.eclipse.epsilon.emc.simulink.model.element.StateflowBlock;
import org.eclipse.epsilon.emc.simulink.operations.contributors.ModelOperationContributor;
import org.eclipse.epsilon.emc.simulink.util.MatlabEngineUtil;
import org.eclipse.epsilon.emc.simulink.util.SimulinkUtil;
import org.eclipse.epsilon.eol.exceptions.EolInternalException;
import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
import org.eclipse.epsilon.eol.exceptions.models.EolEnumerationValueNotFoundException;
import org.eclipse.epsilon.eol.exceptions.models.EolModelElementTypeNotFoundException;
import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException;
import org.eclipse.epsilon.eol.exceptions.models.EolNotInstantiableModelElementTypeException;
import org.eclipse.epsilon.eol.execute.introspection.IPropertyGetter;
import org.eclipse.epsilon.eol.execute.introspection.IPropertySetter;
import org.eclipse.epsilon.eol.execute.operations.contributors.IOperationContributorProvider;
import org.eclipse.epsilon.eol.execute.operations.contributors.OperationContributor;
import org.eclipse.epsilon.eol.models.CachedModel;
import org.eclipse.epsilon.eol.models.IRelativePathResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimulinkModel extends CachedModel<ISimulinkModelElement> implements IOperationContributorProvider {

	/** CONSTANTS */
	public static final String PROPERTY_FILE = "file";
	public static final String PROPERTY_LIBRARY_PATH = "library_path";
	public static final String PROPERTY_ENGINE_JAR_PATH = "engine_jar_path";
	public static final String PROPERTY_SHOW_IN_MATLAB_EDITOR = "hidden_editor";
	public static final String PROPERTY_FOLLOW_LINKS = "follow_links";
	public static final String PROPERTY_WORKING_DIR = "working_dir";

	public static final String BLOCK = "Block";
	public static final String SIMULINK = "Simulink";
	public static final String STATEFLOW = "Stateflow";

	public static final String PWD = "cd '?';";
	public static final String GET_PARAM = "get_param('?', 'Handle');";
	public static final String LOAD_SYSTEM = "load_system('?')";
	public static final String OPEN_SYSTEM = "open_system('?')";
	public static final String NEW_SYSTEM = "new_system('?', 'Model');";
	public static final String SAVE_SYSTEM = "save_system('?', '?');";

	private static final Logger LOGGER = LoggerFactory.getLogger(SimulinkModel.class);
	
	//
	private static final Multimap<String, String> createBlockMap = new Multimap<>();
	//
	private static final ArrayList<ArrayList<String>> deleteBlockMap = new ArrayList<>();
	
	static {
		createBlockMap.put("sflib/Chart", "Stateflow.Chart");
		ArrayList<String> chart = new ArrayList<>();
		chart.add("SubSystem");
		chart.add("Stateflow.Chart");
		deleteBlockMap.add(chart);
	}

	/** FIELDS */

	protected File file = null;
	protected SimulinkPropertyGetter propertyGetter;
	protected SimulinkPropertySetter propertySetter;
	protected ModelOperationContributor simulinkOperationContributor;

	protected File workingDir = null;
	protected String libraryPath;
	protected String engineJarPath;
	protected MatlabEngine engine;

	protected boolean showInMatlabEditor = false;
	protected boolean followLinks = true;
	protected double handle = -1;

	@Override
	protected void loadModel() throws EolModelLoadingException { 
		try {
			engine = MatlabEnginePool.getInstance(libraryPath, engineJarPath).getMatlabEngine();
			simulinkOperationContributor = new ModelOperationContributor(engine);
				
			if ((workingDir != null && workingDir.exists())) {
				try {
					engine.eval(PWD, workingDir);
				} catch (Exception ex) {
					LOGGER.info(ex.getMessage());
				}
			}
			
			if (readOnLoad) {
				String cmd = showInMatlabEditor ? OPEN_SYSTEM : LOAD_SYSTEM;
				try{
					engine.eval(cmd, file.getAbsolutePath());				
				} catch (Exception e) {
					try {
						engine.eval(NEW_SYSTEM, getSimulinkModelName());
					} catch (Exception ex) {
						// Ignore; system already exists
					}
				}
			} else {
				try {
					engine.eval(NEW_SYSTEM, getSimulinkModelName());
				} catch (Exception ex) {
					// Ignore; system already exists
				}
			}
			
			this.handle = (Double) engine.evalWithResult(GET_PARAM, getSimulinkModelName());
		} catch (Exception e) {
			throw new EolModelLoadingException(e, this);
		}
	}
	
	@Override
	protected void disposeModel() { 
		try {
			MatlabEnginePool.getInstance(libraryPath, engineJarPath).release(engine);
		} catch (MatlabRuntimeException e) {
			
		}
	}

	@Override
	protected ISimulinkModelElement createInstanceInModel(String type)
			throws EolModelElementTypeNotFoundException, EolNotInstantiableModelElementTypeException { 
		if (type.contains("/")) {
			try {
				return new SimulinkBlock(this, engine, type);
			} catch (MatlabRuntimeException e) {
				throw new EolNotInstantiableModelElementTypeException(getSimulinkModelName(), type);
			}
		} else if (type.startsWith(STATEFLOW + ".")) {
			try {
				return new StateflowBlock(this, engine, type);
			} catch (MatlabException e) {
				throw new EolNotInstantiableModelElementTypeException(getSimulinkModelName(), type);
			}
		} else {
			throw new EolModelElementTypeNotFoundException(type, null);
		}
	}
	
	@Override
	protected void addToCache(String type, ISimulinkModelElement instance) throws EolModelElementTypeNotFoundException {
		for (String kind : getAllTypeNamesOf(instance)) {
			Object kindCacheKey = getCacheKeyForType(kind);
			kindCache.putIfPresent(kindCacheKey, instance);
		}
	}

	@Override
	protected void removeFromCache(ISimulinkModelElement instance) throws EolModelElementTypeNotFoundException {
		for (String kind : getAllTypeNamesOf(instance)) {
			final Object kindCacheKey = getCacheKeyForType(kind);
			kindCache.remove(kindCacheKey, instance);
		}
	}
		
	@Override
	public void deleteElement(Object o) throws EolRuntimeException {
		deleteElementInModel(o);
		if (isCachingEnabled()) {
			if (o instanceof ISimulinkModelElement) {
				removeFromCache((ISimulinkModelElement) o);
				String type = ((ISimulinkModelElement) o).getType();
				for (List<String> specialType : deleteBlockMap) {
					if (specialType.contains(type)) {
						for (String equivalent : specialType) {
							if (!equivalent.equals(type)) {
								kindCache.replaceValues(equivalent, getAllOfTypeFromModel(equivalent)); // refresh for type
							}
						}
					}
				}
			}
		}
	}

	@Override
	public ISimulinkModelElement createInstance(String type)
			throws EolModelElementTypeNotFoundException, EolNotInstantiableModelElementTypeException {
		ISimulinkModelElement instance = createInstanceInModel(type);
		if (isCachingEnabled()) {
			addToCache(instance.getType(), instance);
			if (createBlockMap.containsKey(type)){
				for (String equivalent : createBlockMap.get(type)){
					kindCache.replaceValues(equivalent, getAllOfTypeFromModel(equivalent)); // refresh for type
				}
			}
		}
		return instance;
	}
	
	@Override
	public Object createInstance(String type, Collection<Object> parameters) 
			throws EolModelElementTypeNotFoundException, EolNotInstantiableModelElementTypeException { 
		if (type.startsWith(STATEFLOW) && parameters.size() == 1) {
			Object parentObject = parameters.toArray()[0];
			try {
				if (parentObject instanceof StateflowBlock) {
					try {
						StateflowBlock instance = new StateflowBlock(this, engine, type, (StateflowBlock) parentObject);
						if (isCachingEnabled()) {
							addToCache(instance.getType(), instance);
							if (createBlockMap.containsKey(type)){
								for (String equivalent : createBlockMap.get(type)){
									kindCache.replaceValues(equivalent, getAllOfTypeFromModel(equivalent)); // refresh for type
								}
							}
						}
						return instance; 
					} catch (MatlabException e) {
						throw new EolModelElementTypeNotFoundException(type, null, e.getMessage());
					}
				} else { 
					throw new EolModelElementTypeNotFoundException(type, null, "invalid parameters");
				}
			} catch (EolRuntimeException e) {
				throw new EolModelElementTypeNotFoundException(type, null, e.getMessage());
			}
		} 
		throw new EolModelElementTypeNotFoundException(type, null);
	}

	@Override
	protected boolean deleteElementInModel(Object instance) throws EolRuntimeException { 
		try {
			if (instance instanceof ISimulinkModelElement) 
				return ((ISimulinkModelElement) instance).deleteElementInModel();
			return false;
		} catch (Exception e) {
			throw new EolInternalException(e);
		}
	}
	
	@Override
	protected Object getCacheKeyForType(String type) throws EolModelElementTypeNotFoundException { 
		return type;		
	}
	
	// COLLECTORS 

	@Override
	protected Collection<String> getAllTypeNamesOf(Object instance) { 
		if (instance instanceof ISimulinkModelElement) {
			return ((ISimulinkModelElement) instance).getAllTypeNamesOf();
		} else {
			return Arrays.asList(getTypeNameOf(instance));
		}
	}

	@Override 
	protected Collection<ISimulinkModelElement> allContentsFromModel() { 
		return TypeHelper.getAll(engine, this);
	}
	
	@Override // FIXME
	protected Collection<ISimulinkModelElement> getAllOfTypeFromModel(String type) 
			throws EolModelElementTypeNotFoundException { 
		return TypeHelper.getAllOfType(this, engine, type);		
	}

	@Override
	protected Collection<ISimulinkModelElement> getAllOfKindFromModel(String kind)  
			throws EolModelElementTypeNotFoundException {
		try {
			try {
				return Kind.get(kind).getAll(this);
			} catch (Exception e) {
				return getAllOfTypeFromModel(kind);
			}
		} catch (Exception e) {
			throw new EolModelElementTypeNotFoundException(null, null);
		}
	}
	
	public static void main(String[] args) throws Exception {
		File tmpFile = File.createTempFile("foo", ".slx");
		
		SimulinkModel model = new SimulinkModel();
		model.setName("M");
		model.setFile(tmpFile);
		model.setWorkingDir(null);
		model.setReadOnLoad(false);
		model.setStoredOnDisposal(false);
		model.setShowInMatlabEditor(true);
		model.setFollowLinks(false);
		//model.setEngineJarPath(MatlabEngineFilesEnum.ENGINE_JAR.path());
		//model.setLibraryPath(MatlabEngineFilesEnum.LIBRARY_PATH.path());
		model.load();
		System.out.println(model.getAllOfType("Gain"));
	}

	public void load(StringProperties properties, IRelativePathResolver resolver) throws EolModelLoadingException { 
		super.load(properties, resolver);

		String filePath = properties.getProperty(SimulinkModel.PROPERTY_FILE);
		String workingDirPath = properties.getProperty(SimulinkModel.PROPERTY_WORKING_DIR);
		if (properties.hasProperty(SimulinkModel.PROPERTY_LIBRARY_PATH))
			libraryPath = properties.getProperty(SimulinkModel.PROPERTY_LIBRARY_PATH);
		if (properties.hasProperty(SimulinkModel.PROPERTY_ENGINE_JAR_PATH))
			engineJarPath = properties.getProperty(SimulinkModel.PROPERTY_ENGINE_JAR_PATH);
		if (properties.hasProperty(SimulinkModel.PROPERTY_SHOW_IN_MATLAB_EDITOR))
			showInMatlabEditor = properties.getBooleanProperty(SimulinkModel.PROPERTY_SHOW_IN_MATLAB_EDITOR, false);
		if (properties.hasProperty(SimulinkModel.PROPERTY_FOLLOW_LINKS))
			followLinks = properties.getBooleanProperty(SimulinkModel.PROPERTY_FOLLOW_LINKS, true);
		if (filePath != null && filePath.trim().length() > 0)
			file = new File(resolver.resolve(filePath));
		if (workingDirPath != null && workingDirPath.trim().length() > 0) {
			workingDir = new File(resolver.resolve(filePath));
		}			

		load();
	}

	public void simulate() throws InterruptedException {
		String name = getFile().getName().substring(0, getFile().getName().lastIndexOf("."));
		Future<Void> fSim;
		try {
			fSim = engine.evalAsync("simout = sim('" + name + "', []);");
			while (!fSim.isDone()) {
				Thread.sleep(1000);
			}
		} catch (MatlabException e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean hasType(String type) {
		return true; // FIXME No validation?
	}
	
	@Override
	public String getTypeNameOf(Object instance) { 
		if (instance instanceof ISimulinkModelElement) {
			return ((ISimulinkModelElement) instance).getType();
		}
		return instance.getClass().getSimpleName().replace(SIMULINK, "");
	}
	
	@Override
	public Object getElementById(String id) { 
		return null;
	}

	@Override
	public void setElementId(Object instance, String newId) {	 
	}
	
	@Override
	public String getElementId(Object instance) { 
		try {
			return (String) propertyGetter.invoke(instance, "id");
		} catch (EolRuntimeException e) {
			return "";
		}
	}

	@Override
	public boolean owns(Object instance) {
		if (instance == null) {
			return false;
		}
		return ((instance instanceof ISimulinkModelElement) 
				&& ((ISimulinkModelElement) instance).getOwningModel() == this ) 
				|| (instance instanceof SimulinkModel)
				|| (instance.getClass().getCanonicalName().startsWith("org.eclipse.epsilon.emc.simulink.types"));
	}

	@Override
	public boolean store(String location) { 
		try {
			engine.eval(SAVE_SYSTEM, getSimulinkModelName(), location);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
	
	@Override
	public boolean store() { 
		store(file.getAbsolutePath());
		return true;
	}

	@Override
	public Object getEnumerationValue(String enumeration, String label) throws EolEnumerationValueNotFoundException {  
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean isInstantiable(String type) { 
		return hasType(type);
	}

	public String getSimulinkModelName() { 
		String name = file.getName();
		int pos = name.lastIndexOf(".");
		if (pos > 0) {
			name = name.substring(0, pos);
		}
		return name;
	}
	
	@Override
	public IPropertySetter getPropertySetter() { 
		if (propertySetter == null) {
			propertySetter = new SimulinkPropertySetter(engine);
		}
		return propertySetter;
	}

	@Override
	public IPropertyGetter getPropertyGetter() { 
		if (propertyGetter == null) {
			propertyGetter = new SimulinkPropertyGetter();
		}
		return propertyGetter;
	}

	@Override
	public OperationContributor getOperationContributor() { 
		return simulinkOperationContributor;
	}

	public File getFile() { 
		return file;
	}

	public void setFile(File file) { 
		this.file = file;
	}

	public MatlabEngine getEngine() { 
		return engine;
	}

	public Double getHandle() { 
		return handle;
	}

	public String getLibraryPath() { 
		return libraryPath;
	}

	public void setLibraryPath(String libraryPath) { 
		this.libraryPath = libraryPath;
	}

	public String getEngineJarPath() { 
		return engineJarPath;
	}

	public void setEngineJarPath(String engineJarPath) { 
		this.engineJarPath = engineJarPath;
	}

	public boolean isShowInMatlabEditor() {
		return showInMatlabEditor;
	}
	
	public File getWorkingDir() {
		return workingDir;
	}

	public void setWorkingDir(File workingDir) {
		this.workingDir = workingDir;
	}
	
	/**
	 * If true, the model will be shown in the MATLAB Editor. 
	 * If the model is already loaded, it will not open it again. 
	 * If false, the model will not be open in the MATLAB editor, 
	 * but won't close an already open model
	 */
	public void setShowInMatlabEditor(boolean openMatlabEditor) { 
		this.showInMatlabEditor = openMatlabEditor;
	}

	public boolean isFollowLinks() {
		return followLinks;
	}

	/**
	 * If true, adds the 'Follow_Link' parameter to the 'find_system' method in MATLAB 
	 */
	public void setFollowLinks(boolean followLinks) {
		this.followLinks = followLinks;
	}

	public Object parseMatlabEngineVariable(String variableName) throws MatlabException { 
		return MatlabEngineUtil.parseMatlabEngineVariable(engine, variableName);
	}
	
	public void statement(String statement) throws EolRuntimeException {
		try{
			engine.eval(statement);
		} catch (MatlabException e) {
			throw new EolRuntimeException(e.getMessage());
		}
	}
	
	public Object statementWithResult(String statement) throws EolRuntimeException {
		try{
			return engine.evalWithResult(statement);
		} catch (MatlabException e) {
			throw new EolRuntimeException(e.getMessage());
		}
	}
	
	public Object getWorkspaceVariable(String value) {
		try {
			return MatlabEngineUtil.parseMatlabEngineVariable(engine,value);
		} catch (MatlabException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public Collection<ISimulinkModelElement> getChildren() throws MatlabException {
		return SimulinkUtil.findBlocks(this,1);
	}
	
	public Collection<ISimulinkModelElement> findBlocks() throws MatlabException{
		return SimulinkUtil.findBlocks(this,1);
	}
	
	public Collection<ISimulinkModelElement> findBlocks(Integer depth) throws MatlabException {
		return SimulinkUtil.findBlocks(this,depth);
	}

}
