package org.eclipse.basyx.components.provider;

import java.util.Collection;
import java.util.HashSet;
import java.util.Map;

import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.qualifier.haskind.ModelingKind;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.facade.SubmodelFacadeCustomSemantics;
import org.eclipse.basyx.submodel.metamodel.facade.SubmodelFacadeIRDISemantics;
import org.eclipse.basyx.submodel.metamodel.map.SubModel;
import org.eclipse.basyx.submodel.metamodel.map.identifier.Identifier;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.AdministrativeInformation;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasDataSpecification;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.LangStrings;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.Referable;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable;
import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifier;
import org.eclipse.basyx.submodel.metamodel.map.reference.Key;
import org.eclipse.basyx.submodel.metamodel.map.reference.Reference;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.restapi.SubModelProvider;
import org.eclipse.basyx.submodel.restapi.MultiSubmodelElementProvider;
import org.eclipse.basyx.submodel.restapi.vab.VABSubmodelAPI;
import org.eclipse.basyx.vab.modelprovider.map.VABMapProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Base class for providers that receiver their configuration through a configuration properties object
 * 
 * @author kuhn
 *
 */

public class BaseConfiguredProvider extends SubModelProvider {
	
	/**
	 * Initiates a logger using the current class
	 */
	private static final Logger logger = LoggerFactory.getLogger(BaseConfiguredProvider.class);

	/**
	 * This is a sub model
	 */
	protected SubModel submodelData = null;
	
	public static final String SUBMODELSEMANTICS = "submodelSemantics";
	public static final String TYPE = "type";
	public static final String SEMANTICSINTERNAL = "semanticsInternal";
	
	public static final String SUBMODELID = "submodelID";
	

	/**
	 * Constructor
	 */
	public BaseConfiguredProvider(Map<Object, Object> cfgValues) {
		// Invoke base constructor
		super();

		// Create sub model
		submodelData = createSubModel(cfgValues);

		setSubmodel(submodelData);
	}

	protected void setSubmodel(SubModel sm) {
		setAPI(new VABSubmodelAPI(new VABMapProvider(sm)));
	}

	/**
	 * Split a comma delimited string
	 * 
	 * @param input
	 *            String input
	 */
	protected Collection<String> splitString(String input) {
		// Return value
		HashSet<String> result = new HashSet<>();

		// Split string into segments
		for (String inputStr : input.split(","))
			result.add(inputStr.trim());

		// Return result
		return result;
	}

	/**
	 * Get list of configured properties
	 * 
	 * @param cfgValues
	 *            Provider configuration
	 */
	protected Collection<String> getConfiguredProperties(Map<Object, Object> cfgValues) {
		// Split property string
		return splitString((String) cfgValues.get(MultiSubmodelElementProvider.ELEMENTS));
	}

	/**
	 * Output a hash map
	 */
	@SuppressWarnings({ "rawtypes" })
	protected void printHashMap(Map map, int indent) {
		// Process map
		for (Object key : map.keySet()) {
			// Process map element
			if (map.get(key) instanceof Map) {
				// Output key
				for (int i = 0; i < indent; i++)
					logger.debug(" ");
				logger.debug("  " + key);
				// Output hash map
				printHashMap((Map) map.get(key), indent + 2);
			} else {
				// Output element
				for (int i = 0; i < indent; i++)
					logger.debug(" ");
				logger.debug("  " + key + " = " + map.get(key));
			}
		}
	}

	/**
	 * Split a key based on path '/' separators
	 */
	protected String[] splitPath(String path) {
		return path.split("/");
	}

	/**
	 * Create BaSys sub model based on configuration data
	 * 
	 * @param cfgValues
	 *            Provider configuration
	 */
	protected SubModel createSubModel(Map<Object, Object> cfgValues) {
		// Create sub model
		SubModel submodel = null;

		// Try to load and convert configuration values. Keep value null if any error occurs
		String basyx_submodelSemantics = null;
		try {
			basyx_submodelSemantics = cfgValues.get(buildBasyxCfgName(SUBMODELSEMANTICS)).toString().toLowerCase();
		} catch (Exception e) {
		}
		String basyx_idType = null;
		try {
			basyx_idType = cfgValues.get(buildBasyxCfgName(Identifier.IDTYPE)).toString().toLowerCase();
		} catch (Exception e) {
		}
		String basyx_id = null;
		try {
			basyx_id = cfgValues.get(buildBasyxCfgName(Identifier.ID)).toString();
		} catch (Exception e) {
		}
		String basyx_idShort = null;
		try {
			basyx_idShort = cfgValues.get(buildBasyxCfgName(Referable.IDSHORT)).toString();
		} catch (Exception e) {
		}
		String basyx_category = null;
		try {
			basyx_category = cfgValues.get(buildBasyxCfgName(Referable.CATEGORY)).toString();
		} catch (Exception e) {
		}
		String basyx_description = null;
		try {
			basyx_description = cfgValues.get(buildBasyxCfgName(Referable.DESCRIPTION)).toString();
		} catch (Exception e) {
		}
		String basyx_qualifier = null;
		try {
			basyx_qualifier = cfgValues.get(buildBasyxCfgName(Qualifier.QUALIFIER)).toString();
		} catch (Exception e) {
		}
		String basyx_qualifierType = null;
		try {
			basyx_qualifierType = cfgValues.get(buildBasyxCfgName(Qualifier.QUALIFIER, Qualifier.TYPE)).toString();
		} catch (Exception e) {
		}
		String basyx_version = null;
		try {
			basyx_version = cfgValues.get(buildBasyxCfgName(AdministrativeInformation.VERSION)).toString();
		} catch (Exception e) {
		}
		String basyx_revision = null;
		try {
			basyx_revision = cfgValues.get(buildBasyxCfgName(AdministrativeInformation.REVISION)).toString();
		} catch (Exception e) {
		}

		// Process ID Type - default value is internal
		IdentifierType idType = IdentifierType.CUSTOM;
		// - Compare to known values
		if (basyx_idType == null)
			basyx_idType = "IdentifierType.Custom";
		if (basyx_idType.equals("IdentifierType.IRDI"))
			idType = IdentifierType.IRDI;
		if (basyx_idType.equals("IdentifierType.URI"))
			idType = IdentifierType.IRI;
		if (basyx_idType.equals("IdentifierType.Custom"))
			idType = IdentifierType.CUSTOM;

		// Try to load properties
		// Check type of sub model template to use
		if (basyx_submodelSemantics == null)
			basyx_submodelSemantics = IdentifierType.CUSTOM.toString().toLowerCase();
		if (basyx_submodelSemantics.equals(IdentifierType.IRDI.toString().toLowerCase())) {
			// Create sub model from template
			submodel = new SubmodelFacadeIRDISemantics(basyx_submodelSemantics, idType, basyx_id,
					basyx_idShort, basyx_category, new LangStrings("", basyx_description),
					new Qualifier(basyx_qualifierType, basyx_qualifier, "", null), null, ModelingKind.INSTANCE, basyx_version,
					basyx_revision);
		}
		if (basyx_submodelSemantics.equals(IdentifierType.CUSTOM.toString().toLowerCase())) {
			// Create sub model from template
			submodel = new SubmodelFacadeCustomSemantics(basyx_submodelSemantics, idType, basyx_id,
					basyx_idShort, basyx_category, new LangStrings("", basyx_description),
					new Qualifier(basyx_qualifierType, basyx_qualifier, "", null), new HasDataSpecification(),
					ModelingKind.INSTANCE, basyx_version, basyx_revision);
		}

		// If no sub model was created, create an empty one
		if (submodel == null)
			submodel = new SubModel();

		// Return sub model data
		return submodel;
	}

	/**
	 * Create a property with given name
	 * 
	 * @param propertyName
	 *            Property name
	 * @param propertyValue
	 *            Property value
	 * @param cfgValues
	 *            Provider configuration
	 */
	protected Property createSubmodelElement(String propertyName, Object propertyValue, Map<Object, Object> cfgValues) {

		// Get property type
		String propertyType = cfgValues.get(buildCfgName(propertyName, TYPE)).toString();

		// Dispatch to requested create function
		if (propertyType.equals("Property"))
			return createProperty(propertyName, propertyValue, cfgValues);

		// Do not return anything
		return null;
	}

	/**
	 * Create a single valued property with given name
	 * 
	 * @param propertyName
	 *            Property name
	 * @param propertyValue
	 *            Property value
	 * @param cfgValues
	 *            Provider configuration
	 */
	protected Property createProperty(String propertyName, Object propertyValue, Map<Object, Object> cfgValues) {

		// Try to get property meta data
		String property_semanticsInternal = null;
		try {
			property_semanticsInternal = cfgValues.get(buildCfgName(propertyName, SEMANTICSINTERNAL)).toString();
		} catch (Exception e) {
		}
		String property_qualifier = null;
		try {
			property_qualifier = cfgValues.get(buildCfgName(propertyName, Qualifier.QUALIFIER)).toString();
		} catch (Exception e) {
		} // might need to rename to constraints
		String property_qualifierType = null;
		try {
			property_qualifierType = cfgValues.get(buildCfgName(propertyName, Qualifier.QUALIFIER, Qualifier.TYPE)).toString();
		} catch (Exception e) {
		}
		String property_description = null;
		try {
			property_description = cfgValues.get(buildCfgName(propertyName, Referable.DESCRIPTION)).toString();
		} catch (Exception e) {
		}

		// Create and return single valued property
		Property prop = new Property(
				propertyValue, 
				new Referable(propertyName, "", new LangStrings("", property_description)),
				new Reference(new Key(KeyElements.PROPERTY, true, property_semanticsInternal, IdentifierType.CUSTOM)), 
				new Qualifiable(new Qualifier(property_qualifierType, property_qualifier, "", null)));
		return prop;
	}
	
	public static String buildBasyxCfgName(String... valueName) {
		return buildCfgName("basyx", valueName);
	}
	
	public static String buildCfgName(String propertyName, String... valueName) {
		String result = propertyName;
		for(String s: valueName)
			result += "." + s;
		return result;
	}
	
}
