/********************************************************************************
 * 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.service;

import static org.eclipse.mdm.businessobjects.control.ContextActivity.CONTEXT_GROUP_MEASURED;
import static org.eclipse.mdm.businessobjects.control.ContextActivity.CONTEXT_GROUP_ORDERED;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.ws.rs.BadRequestException;

import org.eclipse.mdm.api.base.Transaction;
import org.eclipse.mdm.api.base.model.ContextComponent;
import org.eclipse.mdm.api.base.model.ContextDescribable;
import org.eclipse.mdm.api.base.model.ContextRoot;
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.base.model.Measurement;
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.dflt.EntityManager;
import org.eclipse.mdm.api.dflt.model.EntityFactory;
import org.eclipse.mdm.api.dflt.model.TemplateRoot;
import org.eclipse.mdm.api.dflt.model.TemplateTestStep;
import org.eclipse.mdm.businessobjects.control.MDMEntityAccessException;
import org.eclipse.mdm.businessobjects.entity.ContextCollection;
import org.eclipse.mdm.businessobjects.entity.ContextResponse;
import org.eclipse.mdm.businessobjects.entity.MDMAttribute;
import org.eclipse.mdm.businessobjects.entity.MDMEntity;
import org.eclipse.mdm.businessobjects.utils.Decomposer;
import org.eclipse.mdm.businessobjects.utils.ISODateDeseralizer;
import org.eclipse.mdm.businessobjects.utils.Serializer;
import org.eclipse.mdm.connector.boundary.ConnectorService;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.google.common.base.Strings;

import io.vavr.Lazy;
import io.vavr.Value;
import io.vavr.collection.HashMap;
import io.vavr.collection.List;
import io.vavr.collection.Map;
import io.vavr.control.Try;

/**
 * Class providing basic data access methods to contexts.
 * 
 * @author Johannes Stamm, PeakSolution GmbH Nuernberg
 *
 */
@Stateless
public class ContextService {

	@Inject
	private ConnectorService connectorService;

	@EJB
	private EntityService entityService;

	/**
	 * Vavr conform version of contextActivity getTestStepContext function.
	 * 
	 * returns the ordered and measurement context for a {@link TestStep}. If no
	 * {@link ContextType}s are defined for this method call, the method returns all
	 * context informations of the available {@link ContextType}s. Otherwise you can
	 * specify a list of {@link ContextType}s.
	 * 
	 * Possible {@link ContextType}s are {@link ContextType}.UNITUNDERTEST,
	 * {@link ContextType}.TESTSEQUENCE and {@link ContextType}.TESTEQUIPMENT.
	 * 
	 * @param sourceName   name of the source (MDM {@link Environment} name)
	 * @param testStepId   the id of {@link TestStep} context is looked up for
	 * @param contextTypes list of {@link ContextType}s
	 * @return the ordered and measured context data as context object for the
	 *         identified {@link TestStep}
	 */
	public Try<Map<String, Map<ContextType, ContextRoot>>> getTestStepContext(String sourceName, String testStepId,
			ContextType... contextTypes) {
		return getTestStepContext(sourceName, entityService.find(sourceName, TestStep.class, testStepId), contextTypes);
	}

	/**
	 * Vavr conform version of contextActivity getTestStepContext function.
	 * 
	 * returns the ordered and measurement context for a {@link TestStep}. If no
	 * {@link ContextType}s are defined for this method call, the method returns all
	 * context informations of the available {@link ContextType}s. Otherwise you can
	 * specify a list of {@link ContextType}s.
	 * 
	 * Possible {@link ContextType}s are {@link ContextType}.UNITUNDERTEST,
	 * {@link ContextType}.TESTSEQUENCE and {@link ContextType}.TESTEQUIPMENT.
	 * 
	 * @param sourceName   name of the source (MDM {@link Environment} name)
	 * @param testStep     {@link Try} of the {@link TestStep}
	 * @param contextTypes list of {@link ContextType}s
	 * @return the ordered and measured context data as context object for the
	 *         identified {@link TestStep}
	 */
	private Try<Map<String, Map<ContextType, ContextRoot>>> getTestStepContext(String sourceName,
			Try<TestStep> testStep, ContextType... contextTypes) {

		Try<Map<ContextType, ContextRoot>> contextOrdered = entityService.getEntityManager(sourceName)
				.map(e -> HashMap.ofAll(e.loadContexts(testStep.get(), contextTypes)));

		Try<Map<ContextType, ContextRoot>> contextMeasured = entityService.getEntityManager(sourceName).map(
				e -> HashMap.ofAll(e.loadContexts(findMeasurements(sourceName, testStep).get().get(), contextTypes)));

		return Try
				.of(() -> Lazy
						.of(() -> HashMap.of(CONTEXT_GROUP_ORDERED,
								contextOrdered.recover(NoSuchElementException.class, t -> HashMap.empty()).get(),
								CONTEXT_GROUP_MEASURED,
								contextMeasured.recover(NoSuchElementException.class, t -> HashMap.empty()).get()))
						.get());
	}

	/**
	 * Vavr conform version of contextActivity getMeasurementContext function.
	 * 
	 * returns the ordered and measurement context for a {@link Measurement}. If no
	 * {@link ContextType}s are defined for this method call, the method returns all
	 * context informations of the available {@link ContextType}s. Otherwise you can
	 * specify a list of {@link ContextType}s.
	 * 
	 * Possible {@link ContextType}s are {@link ContextType}.UNITUNDERTEST,
	 * {@link ContextType}.TESTSEQUENCE and {@link ContextType}.TESTEQUIPMENT.
	 * 
	 * @param sourceName    name of the source (MDM {@link Environment} name)
	 * @param measurementId the id of {@link Measurement} context is looked up for
	 * @param contextTypes  list of {@link ContextType}s
	 * @return the ordered and measured context data as context object for the
	 *         identified {@link Measurement}
	 */
	public Try<Map<String, Map<ContextType, ContextRoot>>> getMeasurementContext(String sourceName,
			String measurementId, ContextType... contextTypes) {
		return getMeasurementContext(sourceName, entityService.find(sourceName, Measurement.class, measurementId),
				contextTypes);
	}

	/**
	 * Vavr conform version of contextActivity getTestStepContext function.
	 * 
	 * returns the ordered and measurement context for a {@link Measurement}. If no
	 * {@link ContextType}s are defined for this method call, the method returns all
	 * context informations of the available {@link ContextType}s. Otherwise you can
	 * specify a list of {@link ContextType}s.
	 * 
	 * Possible {@link ContextType}s are {@link ContextType}.UNITUNDERTEST,
	 * {@link ContextType}.TESTSEQUENCE and {@link ContextType}.TESTEQUIPMENT.
	 * 
	 * @param sourceName   name of the source (MDM {@link Environment} name)
	 * @param measurement  {@link Try} of the {@link Measurement}
	 * @param contextTypes list of {@link ContextType}s
	 * @return the ordered and measured context data as context object for the
	 *         identified {@link Measurement}
	 */
	private Try<Map<String, Map<ContextType, ContextRoot>>> getMeasurementContext(String sourceName,
			Try<Measurement> measurement, ContextType... contextTypes) {

		Try<Map<ContextType, ContextRoot>> contextOrdered = entityService.getEntityManager(sourceName)
				.map(e -> HashMap.ofAll(e.loadContexts(findTestStep(sourceName, measurement).get(), contextTypes)));

		Try<Map<ContextType, ContextRoot>> contextMeasured = entityService.getEntityManager(sourceName)
				.map(e -> HashMap.ofAll(e.loadContexts(measurement.get(), contextTypes)));

		return Try.of(() -> Lazy.of(() -> HashMap.of(CONTEXT_GROUP_ORDERED, contextOrdered.get(),
				CONTEXT_GROUP_MEASURED, contextMeasured.get())).get());
	}

	/**
	 * 
	 * @param sourceName
	 * @return
	 */
	private Try<EntityManager> getEntityManager(Value<String> sourceName) {
		return Try.of(() -> Lazy.of(() -> connectorService.getContextByName(sourceName.get()).getEntityManager()
				.orElseThrow(() -> new MDMEntityAccessException("Entity manager not present!"))).get());
	}

	/**
	 * 
	 * @param sourceName
	 * @param testStep
	 * @return
	 */
	private Try<List<Measurement>> findMeasurements(String sourceName, Try<TestStep> testStep) {
		return entityService.getEntityManager(sourceName).map(
				e -> Lazy.of(() -> List.ofAll(e.loadChildren(testStep.get(), TestStep.CHILD_TYPE_MEASUREMENT))).get());
	}

	/**
	 * 
	 * @param sourceName
	 * @param testStep
	 * @return
	 */
	private Try<TestStep> findTestStep(String sourceName, Try<Measurement> measurement) {
		return entityService.getEntityManager(sourceName)
				.map(e -> Lazy.of(() -> e.loadParent(measurement.get(), Measurement.PARENT_TYPE_TESTSTEP).get()).get());
	}

	/**
	 * Updates the context of the given ContextDescribable.
	 * 
	 * @param body               update data
	 * @param contextDescribable ContextDescribable to update
	 * @param contextTypes       contextTypes which whould be updated. Empty means
	 *                           all contextTypes.
	 * @return
	 */
	public DescribableContexts updateContext(ContextResponse body, ContextDescribable contextDescribable,
			ContextType... contextTypes) {

		ContextCollection contextCollection = Decomposer.decompose(body::getData).<ContextCollection>getValueAt(0);

		DescribableContexts ec = updateContext(getTestStep(contextDescribable), contextCollection,
				getContextTypes(contextTypes));
		persist(ec);
		return ec;
	}

	private HashMap<String, Object> deserializeRequestBody(String body) {
		ObjectMapper mapper = new ObjectMapper();
		SimpleModule simpleModule = new SimpleModule();
		simpleModule.addDeserializer(Object.class, new ISODateDeseralizer());
		mapper.registerModule(simpleModule);

		try {
			return HashMap.ofAll(mapper.readValue(body, new TypeReference<java.util.Map<String, Object>>() {
			}));
		} catch (IOException e) {
			throw new BadRequestException("Body of request could not be deserialized", e);
		}
	}

	private DescribableContexts updateContext(TestStep testStep, ContextCollection contextCollection,
			ContextType[] contextTypes) {

		Map<ContextType, java.util.List<MDMEntity>> orderedMap = HashMap.ofAll(contextCollection.ordered)
				.filterKeys(t -> Arrays.asList(contextTypes).contains(t));

		DescribableContexts ec = new DescribableContexts();
		ec.setTestStep(testStep);
		ec.setOrdered(updateContextDescribableContext(testStep, orderedMap, contextTypes));

		Map<ContextType, java.util.List<MDMEntity>> measuredMap = HashMap.ofAll(contextCollection.measured)
				.filterKeys(t -> Arrays.asList(contextTypes).contains(t));

		ec.setMeasurements(getEntityManager(testStep.getSourceName()).loadChildren(testStep, Measurement.class));
		ec.getAnyMeasurement().map(m -> updateContextDescribableContext(m, measuredMap, contextTypes))
				.ifPresent(ec::setMeasured);

		return ec;
	}

	private java.util.Map<ContextType, ContextRoot> updateContextDescribableContext(
			ContextDescribable contextDescribable, Map<ContextType, java.util.List<MDMEntity>> rootMap,
			ContextType[] contextTypes) {
		java.util.Map<ContextType, ContextRoot> existingRootMap = getEntityManager(contextDescribable.getSourceName())
				.loadContexts(contextDescribable, contextTypes);

		for (ContextType contextType : contextTypes) {
			ContextRoot existingRoot = existingRootMap.computeIfAbsent(contextType,
					ct -> createContextRoot(contextDescribable, ct));

			rootMap.get(contextType).forEach(newContextRoot -> updateContextRoot(existingRoot, newContextRoot));
		}
		return existingRootMap;
	}

	private ContextRoot createContextRoot(ContextDescribable contextDescribable, ContextType contextType) {
		EntityFactory factory = getEntityFactory(contextDescribable.getSourceName());

		TemplateRoot templateRoot = findTemplateRoot(contextDescribable, contextType);

		if (contextDescribable instanceof Measurement) {
			return factory.createContextRoot((Measurement) contextDescribable, templateRoot);
		} else if (contextDescribable instanceof TestStep) {
			return factory.createContextRoot((TestStep) contextDescribable, templateRoot);
		} else {
			throw new MDMEntityAccessException("Only entities TestStep and Measurement are supported!");
		}
	}

	private void updateContextRoot(ContextRoot existingRoot, java.util.List<MDMEntity> newContextRoot) {
		newContextRoot.forEach(mdmEntity -> {
			ContextComponent comp = existingRoot.getContextComponent(mdmEntity.getName())
					.orElseGet(() -> getEntityFactory(existingRoot.getSourceName())
							.createContextComponent(mdmEntity.getName(), existingRoot));

			updateContextComponent(comp, mdmEntity.getAttributes());
		});
	}

	private void updateContextComponent(ContextComponent contextComponent, java.util.List<MDMAttribute> nameValues) {
		nameValues.forEach(attribute -> Serializer.applyValue(contextComponent.getValue(attribute.getName()),
				attribute.getValue()));
	}

	private TemplateRoot findTemplateRoot(ContextDescribable contextDescribable, ContextType contextType) {
		TestStep testStep;
		if (contextDescribable instanceof Measurement) {
			testStep = getTestStep((Measurement) contextDescribable);
		} else if (contextDescribable instanceof TestStep) {
			testStep = (TestStep) contextDescribable;
		} else {
			throw new MDMEntityAccessException("Only entities TestStep and Measurement are supported!");
		}
		TemplateTestStep tpl = TemplateTestStep.of(testStep).orElseThrow(
				() -> new MDMEntityAccessException("Cannot find TemplateTestStep for TestStep: " + testStep));

		return tpl.getTemplateRoot(contextType).orElseThrow(() -> new MDMEntityAccessException(
				"Cannot find TemplateRoot for ContextType " + contextType + " on Template TestStep " + tpl));
	}

	private TestStep getTestStep(ContextDescribable contextDescribable) {
		if (contextDescribable instanceof TestStep) {
			return (TestStep) contextDescribable;
		} else {
			return getTestStep((Measurement) contextDescribable);
		}
	}

	private TestStep getTestStep(Measurement measurement) {
		return getEntityManager(measurement.getSourceName()).loadParent(measurement, TestStep.class).orElseThrow(
				() -> new MDMEntityAccessException("Cannot find parent TestStep of Measurement: " + measurement));
	}

	private EntityManager getEntityManager(String sourceName) {
		return connectorService.getContextByName(sourceName).getEntityManager()
				.orElseThrow(() -> new MDMEntityAccessException("Entity manager not present!"));
	}

	private EntityFactory getEntityFactory(String sourceName) {
		return connectorService.getContextByName(sourceName).getEntityFactory()
				.orElseThrow(() -> new MDMEntityAccessException("Entity factory not present!"));
	}

	private ContextType[] getContextTypes(ContextType[] types) {
		if (types.length == 0) {
			return ContextType.values();
		} else {
			return types;
		}
	}

	private void persist(DescribableContexts ec) {
		Transaction t = null;
		try {
			// start transaction to persist ValueList
			t = getEntityManager(ec.getTestStep().getSourceName()).startTransaction();

			java.util.Map<Boolean, java.util.List<Entity>> map = ec.getEntities().stream()
					.collect(Collectors.groupingBy(this::isPersisted));

			t.create(map.getOrDefault(Boolean.FALSE, Collections.emptyList()));
			t.update(map.getOrDefault(Boolean.TRUE, Collections.emptyList()));

			// commit the transaction
			t.commit();
		} catch (Exception e) {
			if (t != null) {
				t.abort();
			}
			throw new MDMEntityAccessException(e.getMessage(), e);
		}
	}

	private boolean isPersisted(Entity e) {
		return !Strings.isNullOrEmpty(e.getID()) && !"0".equals(e.getID());
	}

	@SuppressWarnings("unchecked")
	private Map<String, Object> transformMap(Object obj) {
		if (obj instanceof java.util.Map) {
			return HashMap.ofAll(java.util.Map.class.cast(obj));
		} else {
			throw new MDMEntityAccessException(String.format("Expected instance of '%s', but got '%s'",
					java.util.Map.class.getName(), obj.getClass().getName()));
		}
	}

	/**
	 * Casts an {@link Object} holding a {@link java.util.List<Object>} to a
	 * {@link io.vavr.collection.List<Object>}
	 * 
	 * @param obj the {@link Object} to cast
	 * @return the {@link io.vavr.collection.List<Object>}
	 */
	@SuppressWarnings("unchecked")
	private List<Object> transformList(Object obj) {
		if (obj instanceof java.util.List) {
			return List.ofAll(java.util.List.class.cast(obj));
		} else {
			throw new MDMEntityAccessException(String.format("Expected instance of '%s', but got '%s'",
					java.util.List.class.getName(), obj.getClass().getName()));
		}
	}

	private MDMEntity transformToMDMEntity(Map<String, Object> component) {
		return new MDMEntity(
				component.get("name").map(Object::toString)
						.getOrElseThrow(() -> new MDMEntityAccessException("Missing attribute 'name' in MDMEntity")),
				component.get("id").map(Object::toString).getOrElse(""),
				component.get("type").map(Object::toString).getOrElse(""),
				component.get("sourceType").map(Object::toString).getOrElse(""),
				component.get("sourceName").map(Object::toString).getOrElse(""),
				transformList(component.get("attributes").getOrElseThrow(
						() -> new MDMEntityAccessException("Missing attribute 'attributes' in MDMEntity")))
								.map(this::transformMap)
								.map(m -> new MDMAttribute(
										m.get("name").map(Object::toString)
												.getOrElseThrow(() -> new MDMEntityAccessException(
														"Missing attribute 'name' in MDMAttribute")),
										m.get("value").map(Object::toString)
												.getOrElseThrow(() -> new MDMEntityAccessException(
														"Missing attribute 'value' in MDMAttribute")),
										m.get("unit").map(Object::toString).getOrElse(""),
										m.get("datatype").map(Object::toString).getOrElse("")))
								.toJavaList());
	}
}
