/********************************************************************************
 * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 ********************************************************************************/

package org.eclipse.mdm.businessobjects.entity;

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

import org.eclipse.mdm.api.base.adapter.Core;
import org.eclipse.mdm.api.base.model.BaseEntity;
import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.EnumRegistry;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
import org.eclipse.mdm.businessobjects.utils.Serializer;
import org.eclipse.mdm.businessobjects.utils.ServiceUtils;

import io.vavr.Tuple;
import io.vavr.collection.HashMap;

import io.swagger.v3.oas.annotations.media.Schema;

/**
 * MDMEntity (Entity for a business object (contains a list of
 * {@link MDMAttribute}s)
 * 
 * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
 *
 */
@Schema(description = "Representation of a MDM entity")
public class MDMEntity {

	/** name of the MDM business object */
	private String name;
	/** id of the MDM business object */
	private String id;
	/** type as String of the MDM business object (e.g. TestStep) */
	private String type;
	/** source type name of the business object at the data source */
	private String sourceType;
	/** source name (e.g. MDM Environment name) */
	private String sourceName;
	/** list of attribute to transfer */
	private List<MDMAttribute> attributes;
	/** list of relations to transfer */
	private List<MDMRelation> relations;

	/**
	 * Default constructor used for entity deserialization
	 */
	public MDMEntity() {
		// empty lists: in case uncomplete request arrive, what should be the default
		// case
		this.attributes = new ArrayList<>();
		this.relations = new ArrayList<>();
	}

	/**
	 * Constructor.
	 * 
	 * @param entity the business object
	 */
	public MDMEntity(Entity entity) {
		this.name = entity.getName();
		this.id = entity.getID();
		this.type = entity.getClass().getSimpleName();
		this.sourceType = entity.getTypeName();
		this.sourceName = entity.getSourceName();
		this.attributes = convertAttributeValues(entity);
		this.relations = convertRelations(entity);
	}

	/**
	 * Constructor.
	 * 
	 * @param name       Name of the Entity
	 * @param id         ID of the Entity
	 * @param type       Type of the Entity
	 * @param sourceType Source type of the Entity
	 * @param sourceName Source name of the Entity
	 * @param attributes Attributes of the Entity
	 * @param relations  Relations of the Entity
	 */
	public MDMEntity(String name, String id, String type, String sourceType, String sourceName,
			List<MDMAttribute> attributes) {
		this.name = name;
		this.id = id;
		this.type = type;
		this.sourceType = sourceType;
		this.sourceName = sourceName;
		this.attributes = new ArrayList<>(attributes);
		this.relations = new ArrayList<>(relations);
	}

	/**
	 * Constructor.
	 * 
	 * @param name       Name of the Entity
	 * @param id         ID of the Entity
	 * @param type       Type of the Entity
	 * @param sourceType Source type of the Entity
	 * @param sourceName Source name of the Entity
	 * @param attributes Attributes of the Entity
	 * @param relations  Relations of the Entity
	 */
	public MDMEntity(String name, String id, String type, String sourceType, String sourceName,
			List<MDMAttribute> attributes, List<MDMRelation> relations) {
		this.name = name;
		this.id = id;
		this.type = type;
		this.sourceType = sourceType;
		this.sourceName = sourceName;
		this.attributes = new ArrayList<>(attributes);
		this.relations = new ArrayList<>(relations);
	}

	public String getName() {
		return this.name;
	}

	public String getId() {
		return this.id;
	}

	public String getType() {
		return this.type;
	}

	public String getSourceType() {
		return this.sourceType;
	}

	public String getSourceName() {
		return this.sourceName;
	}

	public List<MDMAttribute> getAttributes() {
		return Collections.unmodifiableList(this.attributes);
	}

	public List<MDMRelation> getRelations() {
		return Collections.unmodifiableList(this.relations);
	}

	/**
	 * converts the MDM business object values to string values
	 * 
	 * @param values values of a MDM business object
	 * @return list with converted attribute values
	 */
	private List<MDMAttribute> convertAttributeValues(Entity entity) {
		Map<String, Value> values = entity.getValues();
		List<MDMAttribute> listAttrs = new ArrayList<>();
		HashMap<String, Value> valueMap = HashMap.ofAll(values);

		if (CatalogAttribute.class.equals(entity.getClass())) {
			CatalogAttribute catAttr = (CatalogAttribute) entity;
			if (catAttr.getValueType().isEnumerationType()) {
				valueMap = valueMap.put(Tuple.of(CatalogAttribute.VATTR_ENUMERATION_NAME, ValueType.STRING
						.create(CatalogAttribute.VATTR_ENUMERATION_NAME, catAttr.getEnumerationObject().getName())));
			} else {
				valueMap = valueMap.put(Tuple.of(CatalogAttribute.VATTR_ENUMERATION_NAME,
						ValueType.STRING.create(CatalogAttribute.VATTR_ENUMERATION_NAME)));
			}
			valueMap = valueMap.put(Tuple.of(CatalogAttribute.VATTR_SCALAR_TYPE,
					ValueType.ENUMERATION.create(catAttr.getValueType().toSingleType().name(), "", true, EnumRegistry
							.getInstance().get("ScalarType").valueOf(catAttr.getValueType().toSingleType().name()),
							"")));
			valueMap = valueMap.put(Tuple.of(CatalogAttribute.VATTR_SEQUENCE,
					ValueType.BOOLEAN.create(CatalogAttribute.VATTR_SEQUENCE, catAttr.getValueType().isSequence())));
		}

		for (java.util.Map.Entry<String, Value> entry : valueMap.toJavaMap().entrySet()) {

			if (entry.getKey().equals(BaseEntity.ATTR_ID)) {
				continue;
			}

			if (!entry.getValue().isValid()) {
				String dt = entry.getValue().getValueType().toString();
				listAttrs.add(new MDMAttribute(entry.getKey(), "", "", dt));
				continue;
			}

			if (entry.getValue().getValueType().isSequence()) {
				listAttrs.add(sequenceType2Attribute(entry.getKey(), entry.getValue()));
			} else {
				listAttrs.add(singleType2Attribute(entry.getKey(), entry.getValue()));
			}
		}

		return listAttrs;
	}

	/**
	 * converts a single type MDM business object value to a attribute
	 * 
	 * @param name        name of the attribute value
	 * @param singleValue single MDM business object value
	 * @return the converted attribute value
	 */
	private MDMAttribute singleType2Attribute(String name, Value singleValue) {
		Object value = Serializer.serializeValue(singleValue);
		String unit = singleValue.getUnit();
		String dt = singleValue.getValueType().toString();
		return new MDMAttribute(name, value, unit, dt);
	}

	/**
	 * converts a sequence type MDM business object value to a attribute
	 * 
	 * @param name          name of the attribute value
	 * @param sequenceValue sequence MDM business object value
	 * @return the converted attribute value
	 */
	private MDMAttribute sequenceType2Attribute(String name, Value sequenceValue) {

		if (sequenceValue.getValueType().isStringSequence()) {
			return stringSeq2Attribute(name, sequenceValue);
		} else if (sequenceValue.getValueType().isFileLinkSequence()) {
			String unit = sequenceValue.getUnit();
			String dt = sequenceValue.getValueType().toString();
			return new MDMAttribute(name, Serializer.serializeValue(sequenceValue), unit, dt);
		} else if (sequenceValue.getValueType().isIntegerSequence()) {
			return new MDMAttribute(name, sequenceValue.extract(ValueType.INTEGER_SEQUENCE), sequenceValue.getUnit(),
					sequenceValue.getValueType().toString());
		}

		String dt = sequenceValue.getValueType().toString();
		String defValue = "sequence type '" + dt + "' not implemented yet";
		return new MDMAttribute(name, defValue, "", dt);
	}

	/**
	 * converts a string sequence MDM business object value to a attribute The
	 * result is a separated string (separator: ';')
	 * 
	 * @param name  name of the attribute value
	 * @param value string sequence MDM business object value
	 * @return the converted attribute value
	 */
	private MDMAttribute stringSeq2Attribute(String name, Value value) {
		String[] stringSeq = value.extract();
		StringBuffer sb = new StringBuffer();

		for (String stringSeqValue : stringSeq) {
			sb.append(";").append(stringSeqValue);
		}

		String stringValue = sb.toString().replaceFirst(";", "");
		String unit = value.getUnit();
		String dt = value.getValueType().toString();
		return new MDMAttribute(name, stringValue, unit, dt);
	}

	/**
	 * Converts all relations to MDMRelations. The potential ContextType of the
	 * children is assumed to be the parent's one.
	 * 
	 * @param entity to get
	 *               {@link org.eclipse.mdm.businessobjects.entity.MDMRelation}s for
	 * @return a list of {@link org.eclipse.mdm.businessobjects.entity.MDMRelation}s
	 */
	private List<MDMRelation> convertRelations(Entity entity) {
		// write out children
		Core core = ServiceUtils.getCore(entity);
		// get children hash (type is key)
		return HashMap.ofAll(core.getChildrenStore().getCurrent())
				// on proceed for children that are present
				.filterValues(children -> !children.isEmpty())
				// create child relations (the ContextType is assumed to be same as the parent's
				// one
				.map(entry -> new MDMRelation(null, MDMRelation.RelationType.CHILDREN, entry._1.getSimpleName(),
						ServiceUtils.getContextType(entry._2.get(0)),
						// call get id on all related entities
						io.vavr.collection.List.ofAll(entry._2).map(Deletable::getID).asJava()))
				// append related entities from the mutable store
				.appendAll(io.vavr.collection.List.ofAll(core.getMutableStore().getCurrent()).
				// convert list to map: use simple class name as this is the MDM entity type in
				// conjunction with the ContextType
						groupBy(e -> e.getClass().getSimpleName() + "_" + ServiceUtils.getContextType(e))
						// create relation for every entry
						.map(entry -> new MDMRelation(null, MDMRelation.RelationType.MUTABLE,
								entry._2.get(0).getClass().getSimpleName(),
								ServiceUtils.getContextType(entry._2.get(0)), entry._2.map(Entity::getID).asJava())))
				.appendAll(io.vavr.collection.List.ofAll(core.getPermanentStore().getCurrent())
						.groupBy(e -> e.getClass().getSimpleName())
						// create relation for every entry
						.map(entry -> new MDMRelation(null, MDMRelation.RelationType.PARENT, entry._1,
								ServiceUtils.getContextType(entry._2.get(0)), entry._2.map(Entity::getID).asJava())))
				.asJava();
	}
}
