/********************************************************************************
 * Copyright (c) 2015-2019 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.service;

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import javax.ejb.Stateless;

import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.Environment;
import org.eclipse.mdm.api.dflt.ApplicationContext;
import org.eclipse.mdm.api.dflt.EntityManager;
import org.eclipse.mdm.api.dflt.model.EntityFactory;
import org.eclipse.mdm.api.dflt.model.TemplateAttribute;
import org.eclipse.mdm.api.dflt.model.TemplateComponent;
import org.eclipse.mdm.api.dflt.model.TemplateRoot;
import org.eclipse.mdm.api.dflt.model.TemplateSensor;

import io.vavr.Tuple;
import io.vavr.Value;
import io.vavr.control.Try;

/**
 * {@link TemplateRoot} service handling corresponding operations
 * 
 * @author Philipp Schweinbenz, science+computing AG Tuebingen (Atos SE)
 *
 */
@Stateless
public class TemplateRootService extends EntityService {

	/**
	 * Create new version of {@link TemplateRoot} with given id
	 * 
	 * @param sourceNameSupplier  a {@link Value} with the source name (MDM
	 *                            {@link Environment} name)
	 * @param contextTypeSupplier a {@link Value} with the contextType of entity to
	 *                            create new version of.
	 * @param id                  id of entity to create new version of
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T extends Entity> Try<T> createNewVersion(String sourceName, Value<ContextType> contextTypeSupplier,
			String id) {
		return Try.of(() -> {
			TemplateRoot givenTplRoot = find(sourceName, TemplateRoot.class, id, contextTypeSupplier).get();
			ApplicationContext appContext = connectorService.getContextByName(sourceName);
			TemplateRoot newTplRoot = createNewTplRootVersion(appContext.getEntityFactory().get(),
					appContext.getEntityManager().get(), givenTplRoot);
			Set<Entity> entities = (Set<Entity>) DataAccessHelper.execute(getEntityManager(sourceName).get(),
					Tuple.of(newTplRoot, DataAccessHelper.CREATE));

			return (T) entities.toArray()[0];
		});
	}

	/**
	 * Create new version of given {@link TemplateRoot}
	 * 
	 * @param entityFactory {@link EntityFactory} to create new {@link TemplateRoot}
	 * @param entityManager {@link EntityManager} to get last version of given
	 *                      {@link TemplateRoot}
	 * @param givenTplRoot  {@link TemplateRoot} to create new version of
	 * @return
	 */
	private TemplateRoot createNewTplRootVersion(EntityFactory entityFactory, EntityManager entityManager,
			TemplateRoot givenTplRoot) {
		TemplateRoot newTemplateRoot = entityFactory.createTemplateRoot(givenTplRoot.getContextType(),
				givenTplRoot.getName());
		mergeEntities(givenTplRoot, newTemplateRoot, Entity.ATTR_NAME, Entity.ATTR_MIMETYPE,
				TemplateRoot.ATTR_DATE_CREATED, TemplateRoot.ATTR_VERSION_STATE, TemplateRoot.ATTR_VERSION);
		// TODO pschweinbenzidf on 2019-03-21: Why is this not working correctly with
		// Versionable.COMPARATOR?
		Comparator<TemplateRoot> versionComparator = Comparator.comparing(TemplateRoot::getVersion);
		Optional<Integer> latestVersion = entityManager
				.loadAll(TemplateRoot.class, givenTplRoot.getContextType(), newTemplateRoot.getName()).stream()
				.max(versionComparator).map(TemplateRoot::getVersion);
		if (latestVersion.isPresent()) {
			newTemplateRoot.setVersion(latestVersion.get() + 1);
		}

		for (TemplateComponent tplComp : givenTplRoot.getTemplateComponents()) {
			TemplateComponent newTplComp = entityFactory.createTemplateComponent(tplComp.getName(), newTemplateRoot,
					tplComp.getCatalogComponent());
			mergeEntities(tplComp, newTplComp, Entity.ATTR_NAME, Entity.ATTR_MIMETYPE);

			copyTplAttrs(entityFactory, newTplComp, tplComp.getTemplateAttributes());
			copyChildComps(entityFactory, newTplComp, tplComp.getTemplateComponents());
			copyTplSensors(entityFactory, newTplComp, tplComp.getTemplateSensors());
		}

		return newTemplateRoot;
	}

	/**
	 * Copy given {@link TemplateAttribute}s into given {@link TemplateComponent}
	 * 
	 * @param entityFactory {@link EntityFactory} to create new entities
	 * @param tplComp       {@link TemplateComponent} into given
	 *                      {@link TemplateAttribute}s shall be copied
	 * @param givenTplAttrs {@link TemplateAttribute}s which shall be copied
	 */
	private void copyTplAttrs(EntityFactory entityFactory, TemplateComponent tplComp,
			List<TemplateAttribute> givenTplAttrs) {
		for (TemplateAttribute tplAttr : givenTplAttrs) {
			TemplateAttribute newTplAttr = tplComp.getTemplateAttributes().stream()
					.filter(ta -> ta.getName().equals(tplAttr.getName())).findFirst()
					.orElseGet(() -> entityFactory.createTemplateAttribute(tplAttr.getName(), tplComp));
			mergeEntities(tplAttr, newTplAttr, Entity.ATTR_NAME, Entity.ATTR_MIMETYPE);
		}
	}

	/**
	 * Copy given child {@link TemplateComponent}s into given
	 * {@link TemplateComponent}
	 * 
	 * @param entityFactory   {@link EntityFactory} to create new entities
	 * @param tplComp         {@link TemplateComponent} into given child
	 *                        {@link TemplateComponent}s shall be copied
	 * @param givenChildComps {@link TemplateComponent}s which shall be copied
	 */
	private void copyChildComps(EntityFactory entityFactory, TemplateComponent tplComp,
			List<TemplateComponent> givenChildComps) {
		for (TemplateComponent childComp : givenChildComps) {
			TemplateComponent newTplComp = tplComp.getTemplateComponents().stream()
					.filter(tc -> tc.getName().equals(childComp.getName())).findFirst().orElseGet(() -> entityFactory
							.createTemplateComponent(childComp.getName(), tplComp, childComp.getCatalogComponent()));
			mergeEntities(childComp, newTplComp, Entity.ATTR_NAME, Entity.ATTR_MIMETYPE);

			copyTplAttrs(entityFactory, newTplComp, childComp.getTemplateAttributes());
			copyChildComps(entityFactory, newTplComp, childComp.getTemplateComponents());
			copyTplSensors(entityFactory, newTplComp, childComp.getTemplateSensors());
		}
	}

	/**
	 * Copy given {@link TemplateSeonsor}s into given {@link TemplateComponent}
	 * 
	 * @param entityFactory   {@link EntityFactory} to create new entities
	 * @param tplComp         {@link TemplateComponent} into given
	 *                        {@link TemplateSensor}s shall be copied
	 * @param givenTplSensors {@link TemplateSensor}s which shall be copied
	 */
	private void copyTplSensors(EntityFactory entityFactory, TemplateComponent tplComp,
			List<TemplateSensor> givenTplSensors) {
		for (TemplateSensor tplSensor : givenTplSensors) {
			TemplateSensor newTplSensor = tplComp.getTemplateSensors().stream()
					.filter(ts -> ts.getName().equals(tplSensor.getName())).findFirst()
					.orElseGet(() -> entityFactory.createTemplateSensor(tplSensor.getName(), tplComp,
							tplSensor.getCatalogSensor(), tplSensor.getQuantity()));
			mergeEntities(tplSensor, newTplSensor, Entity.ATTR_NAME, Entity.ATTR_MIMETYPE);

			for (TemplateAttribute tplSensorAttr : tplSensor.getTemplateAttributes()) {
				Optional<TemplateAttribute> newTplSensorAttr = newTplSensor.getTemplateAttributes().stream()
						.filter(ta -> ta.getName().equals(tplSensorAttr.getName())).findFirst();
				if (newTplSensorAttr.isPresent()) {
					mergeEntities(tplSensorAttr, newTplSensorAttr.get(), Entity.ATTR_NAME, Entity.ATTR_MIMETYPE);
				}
			}
		}
	}

	/**
	 * Merge given {@link Entity}s
	 *
	 * @param entity       original {@link Entity} which shall be merged into given
	 *                     updEntity
	 * @param updEntity    {@link Entity} which shall be updated by given entity
	 * @param ignoredAttrs optional attributes which are not merged
	 */
	private void mergeEntities(Entity entity, Entity updEntity, String... ignoredAttrs) {
		if (!entity.getClass().isAssignableFrom(updEntity.getClass())) {
			return;
		}
		Set<String> ingoredAttrs = new HashSet<>(Arrays.asList(ignoredAttrs));

		Map<String, org.eclipse.mdm.api.base.model.Value> entityValues = entity.getValues();
		Set<String> updEntityKeys = updEntity.getValues().keySet();

		for (Map.Entry<String, org.eclipse.mdm.api.base.model.Value> entry : entityValues.entrySet()) {
			String key = entry.getKey();
			if (!ingoredAttrs.contains(key) && updEntityKeys.contains(key)) {
				updEntity.getValue(entry.getKey()).set(entry.getValue().extract());
			}
		}
	}

}
