/*******************************************************************************
 * Copyright (C) 2021 the Eclipse BaSyx Authors
 * 
 * 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.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;
	}
	
}
