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

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map.Entry;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
import org.eclipse.jdt.annotation.NonNull;

// TODO add reporting, e.g. list skipped elements

/**
 * This class provides static methods to extend a model with major elements of a second model.
 */
public class AmaltheaMerger {

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

	/**
	 * Add the contained elements of the input models to the main model.
	 * Only major elements of the model (with their containments) are added.
	 * In case of name conflicts the affected elements will be omitted.
	 *
	 * @param mainModel		model that is extended
	 * @param inputs		list of models that contain the additional elements
	 */
	public static void addElements(final @NonNull Amalthea mainModel, final @NonNull Collection<Amalthea> inputs) {
		checkArgument(mainModel != null, "Model argument is null, expected: Amalthea");
		checkArgument(inputs != null, "Collection argument is null, expected: Collection<Amalthea>");

		if (inputs.isEmpty()) return;	// done

		final Copier copier = new Copier(true, true);

		for (Amalthea model : inputs) {
			final Amalthea tmpModel = (Amalthea) copier.copy(model);
			if (tmpModel == null) continue;

			addPropertiesIfAbsent(mainModel, tmpModel);

			addCommonElements(mainModel, tmpModel);
			addSwModel(mainModel, tmpModel);
			addHwModel(mainModel, tmpModel);
			addOsModel(mainModel, tmpModel);
			addStimuliModel(mainModel, tmpModel);
			addConstraintsModel(mainModel, tmpModel);
			addEventModel(mainModel, tmpModel);
			addPropertyConstraintsModel(mainModel, tmpModel);
			addMappingModel(mainModel, tmpModel);
			addComponentsModel(mainModel, tmpModel);
			addConfigModel(mainModel, tmpModel);
		}
		copier.copyReferences();
	}

	private static void addCommonElements(Amalthea mainModel, Amalthea tmpModel) {
		final CommonElements main = mainModel.getCommonElements();
		final CommonElements tmp = tmpModel.getCommonElements();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setCommonElements(tmp);
		} else {
			addIfAbsent(main.getCoreClassifiers(), tmp.getCoreClassifiers());
			addIfAbsent(main.getMemoryClassifiers(), tmp.getMemoryClassifiers());
			addIfAbsent(main.getTags(), tmp.getTags());
		}
	}

	private static void addSwModel(Amalthea mainModel, Amalthea tmpModel) {
		final SWModel main = mainModel.getSwModel();
		final SWModel tmp = tmpModel.getSwModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setSwModel(tmp);
		} else {
			addIfAbsent(main.getActivations(), tmp.getActivations());
			addIfAbsent(main.getChannels(), tmp.getChannels());
			addIfAbsent(main.getCustomEntities(), tmp.getCustomEntities());
			addIfAbsent(main.getEvents(), tmp.getEvents());
			addIfAbsent(main.getIsrs(), tmp.getIsrs());
			addIfAbsent(main.getLabels(), tmp.getLabels());
			addIfAbsent(main.getModeLabels(), tmp.getModeLabels());
			addIfAbsent(main.getModes(), tmp.getModes());
			addIfAbsent(main.getProcessChains(), tmp.getProcessChains());
			addIfAbsent(main.getProcessPrototypes(), tmp.getProcessPrototypes());
			addIfAbsent(main.getRunnables(), tmp.getRunnables());
			addIfAbsent(main.getSections(), tmp.getSections());
			addIfAbsent(main.getTasks(), tmp.getTasks());
			addIfAbsent(main.getTypeDefinitions(), tmp.getTypeDefinitions());
		}
	}

	private static void addHwModel(Amalthea mainModel, Amalthea tmpModel) {
		final HWModel main = mainModel.getHwModel();
		final HWModel tmp = tmpModel.getHwModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setHwModel(tmp);
		} else {
			addIfAbsent(main.getDefinitions(), tmp.getDefinitions());
			addIfAbsent(main.getDomains(), tmp.getDomains());
			addIfAbsent(main.getFeatureCategories(), tmp.getFeatureCategories());
			addIfAbsent(main.getStructures(), tmp.getStructures());
		}
	}

	private static void addOsModel(Amalthea mainModel, Amalthea tmpModel) {
		final OSModel main = mainModel.getOsModel();
		final OSModel tmp = tmpModel.getOsModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setOsModel(tmp);
		} else {
			addAll(main.getOperatingSystems(), tmp.getOperatingSystems());
			addIfAbsent(main.getOsOverheads(), tmp.getOsOverheads());
			addIfAbsent(main.getSemaphores(), tmp.getSemaphores());
		}
	}

	private static void addStimuliModel(Amalthea mainModel, Amalthea tmpModel) {
		final StimuliModel main = mainModel.getStimuliModel();
		final StimuliModel tmp = tmpModel.getStimuliModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setStimuliModel(tmp);
		} else {
			addIfAbsent(main.getClocks(), tmp.getClocks());
			addIfAbsent(main.getStimuli(), tmp.getStimuli());
		}
	}

	private static void addConstraintsModel(Amalthea mainModel, Amalthea tmpModel) {
		final ConstraintsModel main = mainModel.getConstraintsModel();
		final ConstraintsModel tmp = tmpModel.getConstraintsModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setConstraintsModel(tmp);
		} else {
			addAll(main.getRequirements(), tmp.getRequirements());
			addIfAbsent(main.getEventChains(), tmp.getEventChains());
			addIfAbsent(main.getTimingConstraints(), tmp.getTimingConstraints());
			addIfAbsent(main.getAffinityConstraints(), tmp.getAffinityConstraints());
			addIfAbsent(main.getRunnableSequencingConstraints(), tmp.getRunnableSequencingConstraints());
			addIfAbsent(main.getDataAgeConstraints(), tmp.getDataAgeConstraints());
			addIfAbsent(main.getDataCoherencyGroups(), tmp.getDataCoherencyGroups());
			addIfAbsent(main.getDataStabilityGroups(), tmp.getDataStabilityGroups());
			addIfAbsent(main.getPhysicalSectionConstraints(), tmp.getPhysicalSectionConstraints());
		}
	}

	private static void addEventModel(Amalthea mainModel, Amalthea tmpModel) {
		final EventModel main = mainModel.getEventModel();
		final EventModel tmp = tmpModel.getEventModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setEventModel(tmp);
		} else {
			addIfAbsent(main.getEvents(), tmp.getEvents());
		}
	}

	private static void addPropertyConstraintsModel(Amalthea mainModel, Amalthea tmpModel) {
		final PropertyConstraintsModel main = mainModel.getPropertyConstraintsModel();
		final PropertyConstraintsModel tmp = tmpModel.getPropertyConstraintsModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setPropertyConstraintsModel(tmp);
		} else {
			addAll(main.getAllocationConstraints(), tmp.getAllocationConstraints());
			addAll(main.getMappingConstraints(), tmp.getMappingConstraints());
		}
	}

	private static void addMappingModel(Amalthea mainModel, Amalthea tmpModel) {
		final MappingModel main = mainModel.getMappingModel();
		final MappingModel tmp = tmpModel.getMappingModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setMappingModel(tmp);
		} else {
			if (main.getAddressMappingType() == MemoryAddressMappingType._UNDEFINED_) {
				main.setAddressMappingType(tmp.getAddressMappingType());
			}
			addAll(main.getTaskAllocation(), tmp.getTaskAllocation());
			addAll(main.getIsrAllocation(), tmp.getIsrAllocation());
			addAll(main.getRunnableAllocation(), tmp.getRunnableAllocation());
			addAll(main.getSchedulerAllocation(), tmp.getSchedulerAllocation());
			addAll(main.getMemoryMapping(), tmp.getMemoryMapping());
			addIfAbsent(main.getPhysicalSectionMapping(), tmp.getPhysicalSectionMapping());
		}
	}

	private static void addComponentsModel(Amalthea mainModel, Amalthea tmpModel) {
		final ComponentsModel main = mainModel.getComponentsModel();
		final ComponentsModel tmp = tmpModel.getComponentsModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setComponentsModel(tmp);
		} else {
			addIfAbsent(main.getComponents(), tmp.getComponents());
			addIfAbsent(main.getSystems(), tmp.getSystems());
		}
	}

	private static void addConfigModel(Amalthea mainModel, Amalthea tmpModel) {
		final ConfigModel main = mainModel.getConfigModel();
		final ConfigModel tmp = tmpModel.getConfigModel();
		if (tmp == null) return;

		if (main == null) {
			mainModel.setConfigModel(tmp);
		} else {
			addAll(main.getEventsToTrace(), tmp.getEventsToTrace());
		}
	}

	private static <T extends BaseObject> void addAll(final EList<T> main, final EList<T> input) {
		if (main == null || input == null) return;

		main.addAll(input);
	}

	private static <T extends IReferable> void addIfAbsent(final EList<T> main, final EList<T> input) {
		if (main == null || input == null) return;

		final HashSet<String> uniqueNames = new HashSet<>();
		for (T object : main) {
			if (object != null)
				uniqueNames.add(object.getUniqueName());
		}

		final Collection<T> objectsToMove = new ArrayList<>();
		for (T object : input) {
			if (object == null) continue;

			if (uniqueNames.contains(object.getUniqueName())) {
				// skip entry
			} else {
				// add entry
				objectsToMove.add(object);
			}
		}

		// this part changes the containment of the objects
		main.addAll(objectsToMove);
	}

	private static void addPropertiesIfAbsent(final IAnnotatable main, final IAnnotatable input) {
		if (main == null || input == null) return;

		for (Entry<String, Value> property : input.getCustomProperties()) {
			if (main.getCustomProperties().containsKey(property.getKey())) {
				// skip entry
			} else {
				// add entry
				main.getCustomProperties().add(property);
			}
		}
	}

}
