package org.eclipse.basyx.submodel.types.digitalnameplate.submodelelementcollections.assetspecificproperties;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.basyx.aas.metamodel.exception.MetamodelConstructionException;
import org.eclipse.basyx.submodel.metamodel.api.identifier.IdentifierType;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyElements;
import org.eclipse.basyx.submodel.metamodel.api.reference.enums.KeyType;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IProperty;
import org.eclipse.basyx.submodel.metamodel.facade.SubmodelElementMapCollectionConverter;
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.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.Property;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDef;

/**
 * GuidelineSpecificProperties as defined in the AAS Digital Nameplate Template document <br/>
 * It is a submodel element collection which contains Asset specific nameplate 
 * information required by guideline, stipulation or legislation.
 * 
 * @author haque
 *
 */
public class GuidelineSpecificProperties extends SubmodelElementCollection {
	public static final String GUIDELINEFORCONFORMITYDECLARATIONID = "GuidelineForConformityDeclaration";
	public static final Reference SEMANTICID = new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "https://adminshell.io/zvei/nameplate/1/0/Nameplate/AssetSpecificProperties/GuidelineSpecificProperties", KeyType.IRI));
	
	private GuidelineSpecificProperties() {
	}
	
	/**
	 * Constructor with mandatory attributes
	 * 
	 * @param idShort
	 * @param declaration
	 * @param arbitrary
	 */
	public GuidelineSpecificProperties(String idShort, Property declaration, List<Property> arbitrary) {
		super(idShort);
		setSemanticID(SEMANTICID);
		setGuidelineForConformityDeclaration(declaration);
		setArbitrary(arbitrary);
	}
	
	/**
	 * Constructor with mandatory attributes
	 * 
	 * @param idShort
	 * @param declaration
	 * @param arbitrary
	 */
	public GuidelineSpecificProperties(String idShort, String declaration, List<Property> arbitrary) {
		super(idShort);
		setSemanticID(SEMANTICID);
		setGuidelineForConformityDeclaration(declaration);
		setArbitrary(arbitrary);
	}
	
	/**
	 * Creates a GuidelineSpecificProperties SMC object from a map
	 * 
	 * @param obj a GuidelineSpecificProperties SMC object as raw map
	 * @return a GuidelineSpecificProperties SMC object, that behaves like a facade for the given map
	 */
	public static GuidelineSpecificProperties createAsFacade(Map<String, Object> obj) {
		if (obj == null) {
			return null;
		}
		
		if (!isValid(obj)) {
			throw new MetamodelConstructionException(GuidelineSpecificProperties.class, obj);
		}
		
		GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties();
		guidelineSpecificProperties.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
		return guidelineSpecificProperties;
	}
	
	/**
	 * Creates a GuidelineSpecificProperties SMC object from a map without validation
	 * 
	 * @param obj a GuidelineSpecificProperties SMC object as raw map
	 * @return a GuidelineSpecificProperties SMC object, that behaves like a facade for the given map
	 */
	private static GuidelineSpecificProperties createAsFacadeNonStrict(Map<String, Object> obj) {
		if (obj == null) {
			return null;
		}
		
		GuidelineSpecificProperties guidelineSpecificProperties = new GuidelineSpecificProperties();
		guidelineSpecificProperties.setMap((Map<String, Object>)SubmodelElementMapCollectionConverter.mapToSmECollection(obj));
		return guidelineSpecificProperties;
	}
	
	/**
	 * Check whether all mandatory elements for GuidelineSpecificProperties SMC
	 * exist in the map
	 * 
	 * @param obj
	 * 
	 * @return true/false
	 */
	public static boolean isValid(Map<String, Object> obj) {
		GuidelineSpecificProperties props = createAsFacadeNonStrict(obj);
		
		return SubmodelElementCollection.isValid(obj)
				&& props.getGuidelineForConformityDeclaration() != null
				&& props.getArbitrary() != null
				&& props.getArbitrary().size() > 0;
	}
	
	/**
	 * sets guideline, stipulation or legislation used for determining conformity
	 * 
	 * @param declaration {@link Property}
	 */
	public void setGuidelineForConformityDeclaration(Property declaration) {
		addSubModelElement(declaration);
	}
	
	/**
	 * sets guideline, stipulation or legislation used for determining conformity
	 * 
	 * @param declaration {@link String}
	 */
	public void setGuidelineForConformityDeclaration(String declaration) {
		Property declarationProp = new Property(GUIDELINEFORCONFORMITYDECLARATIONID, PropertyValueTypeDef.String);
		declarationProp.setSemanticID(new Reference(new Key(KeyElements.CONCEPTDESCRIPTION, false, "0173-1#02-AAO856#002", IdentifierType.IRDI)));
		declarationProp.set(declaration);
		setGuidelineForConformityDeclaration(declarationProp);
	}
	
	/**
	 * gets sets guideline, stipulation or legislation used for determining conformity
	 * 
	 * @return
	 */
	public IProperty getGuidelineForConformityDeclaration() {
		return (IProperty) getSubmodelElement(GUIDELINEFORCONFORMITYDECLARATIONID);
	}
	
	/**
	 * Gets arbitrary, representing information required by further standards
	 * @return
	 */
	public List<IProperty> getArbitrary() {
		List<IProperty> ret = new ArrayList<IProperty>();
		Map<String, ISubmodelElement> elemMap = getSubmodelElements();
		if (elemMap != null && elemMap.size() > 0) {
			for (Map.Entry<String, ISubmodelElement> singleElement: elemMap.entrySet()) {
				if (!singleElement.getKey().equals(GUIDELINEFORCONFORMITYDECLARATIONID)) {
					ret.add((IProperty) singleElement.getValue());
				}
			}
		}
		return ret;
	}

	/**
	 * Sets arbitrary, representing information required by further standards
	 * @param arbitraries
	 */
	public void setArbitrary(List<Property> arbitraries) {
		if (arbitraries != null & arbitraries.size() > 0) {
			for (Property prop : arbitraries) {
				addSubModelElement(prop);
			}
		}
	}
}
