package org.eclipse.basyx.submodel.metamodel.connected.submodelelement;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IDataElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.operation.IOperation;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedBlob;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedFile;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedMultiLanguageProperty;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedProperty;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedRange;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.dataelement.ConnectedReferenceElement;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.event.ConnectedBasicEvent;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.operation.ConnectedOperation;
import org.eclipse.basyx.submodel.metamodel.connected.submodelelement.relationship.ConnectedRelationshipElement;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Blob;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.MultiLanguageProperty;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.Range;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.ReferenceElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.event.BasicEvent;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.relationship.RelationshipElement;
import org.eclipse.basyx.vab.modelprovider.VABElementProxy;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;


/**
 * Factory creating connected ISubmodelElements from a given VABElementProxy
 * 
 * @author conradi, espen
 *
 */
public class ConnectedSubmodelElementFactory {

	/**
	 * Creates connected ISubmodelElements from a VABElementProxy
	 * 
	 * @param rootProxy      proxy for the root element
	 * @param collectionPath path in the proxy for accessing all elements
	 * @param elementPath    path in the proxy for accessing single elements by short ids
	 * @return A Map containing the created connected ISubmodelElements and their IDs
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, ISubmodelElement> getConnectedSubmodelElements(VABElementProxy rootProxy,
			String collectionPath, String elementPath) {
		// Query the whole list of elements
		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
				.getModelPropertyValue(collectionPath);
		// Get the type and idShort for each element and create the corresponding connected variant
		Map<String, ISubmodelElement> ret = new HashMap<>();
		for (Map<String, Object> node : mapElemList) {
			String idShort = Referable.createAsFacade(node, KeyElements.SUBMODELELEMENT).getIdShort();
			ISubmodelElement element = getConnectedSubmodelElement(rootProxy, elementPath, idShort, node);
			ret.put(idShort, element);
		}
		return ret;
	}

	/**
	 * Creates a Collection of connected ISubmodelElements from a VABElementProxy
	 * 
	 * @param rootProxy      proxy for the root element
	 * @param collectionPath path in the proxy for accessing all elements
	 * @param elementPath    path in the proxy for accessing single elements by short ids
	 * @return A Collection containing the created connected ISubmodelElements
	 */
	@SuppressWarnings("unchecked")
	public static Collection<ISubmodelElement> getElementCollection(VABElementProxy rootProxy,
			String collectionPath, String elementPath) {
		// Query the whole list of elements
		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
				.getModelPropertyValue(collectionPath);
		// Get the type and idShort for each element and create the corresponding connected variant
		Collection<ISubmodelElement> ret = new ArrayList<>();
		for (Map<String, Object> node : mapElemList) {
			String idShort = Referable.createAsFacade(node, KeyElements.SUBMODELELEMENT).getIdShort();
			ISubmodelElement element = getConnectedSubmodelElement(rootProxy, elementPath, idShort, node);
			ret.add(element);
		}
		return ret;
	}
	
	/**
	 * Creates a connected ISubmodelElement by idShort, proxy and map content
	 * 
	 * @param rootProxy      proxy for the root element
	 * @param collectionPath path in the proxy for accessing all elements
	 * @param elementPath    path in the proxy for accessing single elements by short ids
	 * @return The connected variant of the requested submodel element
	 */
	private static ISubmodelElement getConnectedSubmodelElement(VABElementProxy rootProxy,
			String elementPath, String idShort, Map<String, Object> mapContent) {
		String subPath = VABPathTools.concatenatePaths(elementPath, idShort);
		VABElementProxy proxy = rootProxy.getDeepProxy(subPath);
		if (Property.isProperty(mapContent)) {
			return new ConnectedProperty(proxy);
		} else if (Blob.isBlob(mapContent)) {
			return new ConnectedBlob(proxy);
		} else if (File.isFile(mapContent)) {
			return new ConnectedFile(proxy);
		} else if (SubmodelElementCollection.isSubmodelElementCollection(mapContent)) {
			return new ConnectedSubmodelElementCollection(proxy);
		} else if(MultiLanguageProperty.isMultiLanguageProperty(mapContent)) {
			return new ConnectedMultiLanguageProperty(proxy);
		} else if(Range.isRange(mapContent)) {
			return new ConnectedRange(proxy);
		} else if(ReferenceElement.isReferenceElement(mapContent)) {
			return new ConnectedReferenceElement(proxy);
		} else if (RelationshipElement.isRelationshipElement(mapContent)) {
			return new ConnectedRelationshipElement(proxy);
		} else if (Operation.isOperation(mapContent)) {
			return new ConnectedOperation(proxy);
		} else if(BasicEvent.isBasicEvent(mapContent)) {
			return new ConnectedBasicEvent(proxy);
		} else {
			return null;
		}
	}
	
	/**
	 * Creates connected IOperations from a VABElementProxy
	 * 
	 * @param rootProxy      proxy for the root element
	 * @param collectionPath path in the proxy for accessing all elements
	 * @param elementPath    path in the proxy for accessing single elements by short ids
	 * @return A Map containing the created connected IOperations and their IDs
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, IOperation> getOperations(VABElementProxy rootProxy, String collectionPath,
			String elementPath) {
		// Query the whole list of elements
		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
				.getModelPropertyValue(collectionPath);

		// Get the type and idShort for each operation and create the corresponding connected variant
		Map<String, IOperation> ret = new HashMap<>();
		for (Map<String, Object> node : mapElemList) {
			String idShort = Referable.createAsFacade(node, KeyElements.OPERATION).getIdShort();
			String subPath = VABPathTools.concatenatePaths(elementPath, idShort);
			VABElementProxy proxy = rootProxy.getDeepProxy(subPath);
			if (Operation.isOperation(node)) {
				ret.put(idShort, new ConnectedOperation(proxy));
			}
		}
		return ret;
	}
	
	/**
	 * Creates connected IDataElements from a VABElementProxy
	 * 
	 * @param rootProxy      proxy for the root element
	 * @param collectionPath path in the proxy for accessing all elements
	 * @param elementPath    path in the proxy for accessing single elements by short ids
	 * @return A Map containing the created connected IDataElement and their IDs
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, IDataElement> getDataElements(VABElementProxy rootProxy, String collectionPath,
			String elementPath) {
		// Query the whole list of elements
		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy
				.getModelPropertyValue(collectionPath);

		// Get the type and idShort for each operation and create the corresponding connected variant
		Map<String, IDataElement> ret = new HashMap<>();
		for (Map<String, Object> node : mapElemList) {
			String idShort = Referable.createAsFacade(node, KeyElements.DATAELEMENT).getIdShort();
			String subPath = VABPathTools.concatenatePaths(elementPath, idShort);
			VABElementProxy proxy = rootProxy.getDeepProxy(subPath);
			if (Property.isProperty(node)) {
				ret.put(idShort, new ConnectedProperty(proxy));
			} else if (Blob.isBlob(node)) {
				ret.put(idShort, new ConnectedBlob(proxy));
			} else if (File.isFile(node)) {
				ret.put(idShort, new ConnectedFile(proxy));
			} else if(MultiLanguageProperty.isMultiLanguageProperty(node)) {
				ret.put(idShort, new ConnectedMultiLanguageProperty(proxy));
			} else if(Range.isRange(node)) {
				ret.put(idShort, new ConnectedRange(proxy));
			} else if(ReferenceElement.isReferenceElement(node)) {
				ret.put(idShort, new ConnectedReferenceElement(proxy));
			}
		}
		return ret;
	}
	
	/**
	 * Creates connected IProperty elements from VABElementProxy
	 * 
	 * @param rootProxy
	 * @param collectionPath
	 * @param elementPath
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, IProperty> getProperties(VABElementProxy rootProxy, String collectionPath,
			String elementPath) {
		// Query the whole list of elements
		Collection<Map<String, Object>> mapElemList = (Collection<Map<String, Object>>) rootProxy.getModelPropertyValue(collectionPath);

		// Get the type and idShort for each operation and create the corresponding
		// connected variant
		Map<String, IProperty> ret = new HashMap<>();
		for (Map<String, Object> node : mapElemList) {
			String idShort = Referable.createAsFacade(node, KeyElements.DATAELEMENT).getIdShort();
			String subPath = VABPathTools.concatenatePaths(elementPath, idShort);
			VABElementProxy proxy = rootProxy.getDeepProxy(subPath);
			if (Property.isProperty(node)) {
				ret.put(idShort, new ConnectedProperty(proxy));
			}
		}
		return ret;
	}
}
