/**
 ********************************************************************************
 * Copyright (c) 2019-2020 Robert Bosch GmbH and others.
 * 
 * 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
 * 
 * Contributors:
 *     Robert Bosch GmbH - initial API and implementation
 ********************************************************************************
 */

package org.eclipse.app4mc.amalthea.model.util;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.app4mc.amalthea.model.AbstractEventChain;
import org.eclipse.app4mc.amalthea.model.AbstractProcess;
import org.eclipse.app4mc.amalthea.model.Amalthea;
import org.eclipse.app4mc.amalthea.model.AmaltheaFactory;
import org.eclipse.app4mc.amalthea.model.AmaltheaIndex;
import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
import org.eclipse.app4mc.amalthea.model.ConstraintsModel;
import org.eclipse.app4mc.amalthea.model.EventChainContainer;
import org.eclipse.app4mc.amalthea.model.LimitType;
import org.eclipse.app4mc.amalthea.model.ProcessRequirement;
import org.eclipse.app4mc.amalthea.model.Runnable;
import org.eclipse.app4mc.amalthea.model.RunnableRequirement;
import org.eclipse.app4mc.amalthea.model.SubEventChain;
import org.eclipse.app4mc.amalthea.model.Task;
import org.eclipse.app4mc.amalthea.model.Time;
import org.eclipse.app4mc.amalthea.model.TimeMetric;
import org.eclipse.app4mc.amalthea.model.TimeRequirementLimit;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

public class ConstraintsUtil {

	// Suppress default constructor
	private ConstraintsUtil() {
		throw new IllegalStateException("Utility class");
	}

	private static final String ARG_NULL_MESSAGE = "Argument is null";

	/**
	 * @param process
	 * @return
	 */
	public static @Nullable Time getDeadline(final @NonNull AbstractProcess process) {
		checkArgument(process != null, ARG_NULL_MESSAGE);
		
		final ConstraintsModel constraintsModel = getConstraintsModel(process);
		if (constraintsModel == null) return null;
		
		return getDeadline(process, constraintsModel);
	}

	/**
	 * @param process
	 * @param constModel
	 * @return
	 */
	public static @Nullable Time getDeadline(final @NonNull AbstractProcess process, final @NonNull ConstraintsModel constModel) {
		checkArgument(process != null, ARG_NULL_MESSAGE);
		checkArgument(constModel != null, ARG_NULL_MESSAGE);

		List<Time> list = getDeadlineRequirements(process, constModel).stream()
				.map(req -> ((TimeRequirementLimit) req.getLimit()).getLimitValue())
				.filter(Objects::nonNull)
				.sorted(Time::compareTo)
				.collect(Collectors.toList());
		if (list.isEmpty()) return null;
		
		return list.get(0);
	}

	/**
	 * @param runnable
	 * @return
	 */
	public static @Nullable Time getDeadline(final @NonNull Runnable runnable) {
		checkArgument(runnable != null, ARG_NULL_MESSAGE);
		
		final ConstraintsModel constraintsModel = getConstraintsModel(runnable);
		if (constraintsModel == null) return null;

		return getDeadline(runnable, constraintsModel);
	}

	/**
	 * @param runnable
	 * @param constModel
	 * @return
	 */
	public static @Nullable Time getDeadline(final @NonNull Runnable runnable, final @NonNull ConstraintsModel constModel) {
		checkArgument(runnable != null, ARG_NULL_MESSAGE);
		checkArgument(constModel != null, ARG_NULL_MESSAGE);
		
		List<Time> list = getDeadlineRequirements(runnable, constModel).stream()
				.map(req -> ((TimeRequirementLimit) req.getLimit()).getLimitValue())
				.filter(Objects::nonNull)
				.sorted(Time::compareTo)
				.collect(Collectors.toList());
		if (list.isEmpty()) return null;
		
		return list.get(0);
	}

	// ***** Deadline Requirements *****

	/**
	 * @param container
	 * @param process
	 * @param deadline
	 */
	public static void addNewDeadlineRequirement(final @NonNull ConstraintsModel container, final @NonNull AbstractProcess process, final @NonNull Time deadline) {
		checkArgument(container != null, ARG_NULL_MESSAGE);
		checkArgument(process != null, ARG_NULL_MESSAGE);
		checkArgument(deadline != null, ARG_NULL_MESSAGE);

		final TimeRequirementLimit limit = AmaltheaFactory.eINSTANCE.createTimeRequirementLimit();
		limit.setMetric(TimeMetric.RESPONSE_TIME);
		limit.setLimitType(LimitType.UPPER_LIMIT);
		limit.setLimitValue(deadline);
		final ProcessRequirement req = AmaltheaFactory.eINSTANCE.createProcessRequirement();
		req.setName("Process deadline");
		req.setProcess(process);
		req.setLimit(limit);
		container.getRequirements().add(req);
	}

	/**
	 * @param container
	 * @param runnable
	 * @param deadline
	 */
	public static void addNewDeadlineRequirement(final @NonNull ConstraintsModel container, final @NonNull Runnable runnable, final @NonNull Time deadline) {
		checkArgument(container != null, ARG_NULL_MESSAGE);
		checkArgument(runnable != null, ARG_NULL_MESSAGE);
		checkArgument(deadline != null, ARG_NULL_MESSAGE);

		final TimeRequirementLimit limit = AmaltheaFactory.eINSTANCE.createTimeRequirementLimit();
		limit.setMetric(TimeMetric.RESPONSE_TIME);
		limit.setLimitType(LimitType.UPPER_LIMIT);
		limit.setLimitValue(deadline);
		final RunnableRequirement req = AmaltheaFactory.eINSTANCE.createRunnableRequirement();
		req.setName("Runnable deadline");
		req.setRunnable(runnable);
		req.setLimit(limit);
		container.getRequirements().add(req);
	}

	/**
	 * @param task
	 * @param deadline
	 */
	public static void updateDeadlineRequirement(final @NonNull Task task, final @NonNull Time deadline) {
		checkArgument(task != null, ARG_NULL_MESSAGE);
		checkArgument(deadline != null, ARG_NULL_MESSAGE);
		
		final ConstraintsModel constraintsModel = getConstraintsModel(task);
		if (constraintsModel == null) return;

		updateDeadlineRequirement(task, deadline, constraintsModel);
	}

	/**
	 * @param task
	 * @param deadline
	 * @param constModel
	 */
	public static void updateDeadlineRequirement(final @NonNull Task task, final @NonNull Time deadline, final @NonNull ConstraintsModel constModel) {
		checkArgument(task != null, ARG_NULL_MESSAGE);
		checkArgument(deadline != null, ARG_NULL_MESSAGE);
		checkArgument(constModel != null, ARG_NULL_MESSAGE);

		final List<ProcessRequirement> requirements = getDeadlineRequirements(task, constModel);
		
		if (requirements.isEmpty()) {
			// create deadline requirement
			addNewDeadlineRequirement(constModel, task, deadline);
		} else {
			// modify first deadline requirement
			ProcessRequirement first = requirements.remove(0);
			((TimeRequirementLimit) first.getLimit()).setLimitValue(deadline);
			// delete the rest
			AmaltheaIndex.deleteAll(requirements);
		}
	}

	/**
	 * @param runnable
	 * @param deadline
	 */
	public static void updateDeadlineRequirement(final @NonNull Runnable runnable, final @NonNull Time deadline) {
		checkArgument(runnable != null, ARG_NULL_MESSAGE);
		checkArgument(deadline != null, ARG_NULL_MESSAGE);
		
		final ConstraintsModel constraintsModel = getConstraintsModel(runnable);
		if (constraintsModel == null) return;
		
		updateDeadlineRequirement(runnable, deadline, constraintsModel);
	}

	/**
	 * @param runnable
	 * @param deadline
	 * @param constModel
	 */
	public static void updateDeadlineRequirement(final @NonNull Runnable runnable, final @NonNull Time deadline, final @NonNull ConstraintsModel constModel) {
		checkArgument(runnable != null, ARG_NULL_MESSAGE);
		checkArgument(deadline != null, ARG_NULL_MESSAGE);
		checkArgument(constModel != null, ARG_NULL_MESSAGE);

		final List<RunnableRequirement> requirements = getDeadlineRequirements(runnable, constModel);
		
		if (requirements.isEmpty()) {
			// create deadline requirement
			addNewDeadlineRequirement(constModel, runnable, deadline);
		} else {
			// modify first deadline requirement
			RunnableRequirement first = requirements.remove(0);
			((TimeRequirementLimit) first.getLimit()).setLimitValue(deadline);
			// delete the rest
			AmaltheaIndex.deleteAll(requirements);
		}
	}

	/**
	 * @param runnable
	 * @param constModel
	 * @return
	 */
	public static List<RunnableRequirement> getDeadlineRequirements(final @NonNull Runnable runnable, final @NonNull ConstraintsModel constModel) {
		checkArgument(runnable != null, ARG_NULL_MESSAGE);
		checkArgument(constModel != null, ARG_NULL_MESSAGE);

		return constModel.getRequirements().stream()
			.filter(req -> req.getLimit().getLimitType() == LimitType.UPPER_LIMIT
				&& req instanceof RunnableRequirement
				&& ((RunnableRequirement) req).getRunnable() == runnable
				&& req.getLimit() instanceof TimeRequirementLimit
				&& ((TimeRequirementLimit) req.getLimit()).getMetric() == TimeMetric.RESPONSE_TIME)
			.map(req -> (RunnableRequirement) req)
			.collect(Collectors.toList());
	}

	/**
	 * @param process
	 * @param constModel
	 * @return
	 */
	public static List<ProcessRequirement> getDeadlineRequirements(final @NonNull AbstractProcess process, final @NonNull ConstraintsModel constModel) {
		checkArgument(process != null, ARG_NULL_MESSAGE);
		checkArgument(constModel != null, ARG_NULL_MESSAGE);

		return constModel.getRequirements().stream()
		.filter(req -> req.getLimit().getLimitType() == LimitType.UPPER_LIMIT
			&& req instanceof ProcessRequirement
			&& ((ProcessRequirement) req).getProcess() == process
			&& req.getLimit() instanceof TimeRequirementLimit
			&& ((TimeRequirementLimit) req.getLimit()).getMetric() == TimeMetric.RESPONSE_TIME)
		.map(req -> (ProcessRequirement) req)
		.collect(Collectors.toList());
	}

	/**
	 * Retrieve all abstract event chains from the constraints model.
	 * This includes event chains and sub event chains (contained as items).
	 * @param constModel The constraints model from which we want to have all abstract event chains.
	 * @return All abstract event chains.
	 */
	public static List<AbstractEventChain> getAllAbstractEventChains(final @NonNull ConstraintsModel constModel) {
		checkArgument(constModel != null, ARG_NULL_MESSAGE);
		
		final List<AbstractEventChain> allECs = new ArrayList<>(constModel.getEventChains());
		final Deque<AbstractEventChain> compositeECs = allECs.stream().filter(ec -> !ec.getItems().isEmpty()).collect(Collectors.toCollection(LinkedList::new));
		// search for arbitrarily deep nested sub event chains
		while(!compositeECs.isEmpty()) {
			final AbstractEventChain compositeEC = compositeECs.poll();
			final Set<SubEventChain> subChains = compositeEC.getItems().stream().filter(EventChainContainer.class::isInstance)
					.map(EventChainContainer.class::cast).map(EventChainContainer::getEventChain).collect(Collectors.toSet());
			allECs.addAll(subChains);
			subChains.stream().filter(sec -> !sec.getItems().isEmpty()).forEach(compositeECs::offer);
		}
		
		return allECs;
	}


	@SuppressWarnings("unused")
	private static ConstraintsModel getConstraintsModel(final @NonNull EObject object) {
		checkArgument(object != null, ARG_NULL_MESSAGE);
		
		Amalthea modelRoot = AmaltheaServices.getContainerOfType(object, Amalthea.class);
		if (modelRoot == null) return null;
		
		return ModelUtil.getOrCreateConstraintsModel(modelRoot);
	}

}
