/********************************************************************************
 * 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.api.base.model;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

import org.eclipse.mdm.api.base.adapter.ChildrenStore;
import org.eclipse.mdm.api.base.adapter.Core;
import org.eclipse.mdm.api.base.adapter.EntityStore;

/**
 * Implementation of an abstract entity factory which creates new entities.
 *
 * @since 1.0.0
 * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
 * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
 */
public abstract class BaseEntityFactory {

	// ======================================================================
	// Public methods
	// ======================================================================

	/**
	 * Creates a new {@link Channel}. The name of the returned {@code Channel} is
	 * retrieved from given {@link Quantity}.
	 *
	 * @param measurement The parent {@link Measurement}.
	 * @param quantity    The {@code Quantity} is used for default initialization.
	 * @return The created {@code Channel} is returned.
	 */
	public Channel createChannel(Measurement measurement, Quantity quantity) {
		return createChannel(quantity.getDefaultChannelName(), measurement, quantity);
	}

	/**
	 * Creates a new {@link Channel}.
	 *
	 * @param name        Name of the created {@code Channel}.
	 * @param measurement The parent {@link Measurement}.
	 * @param quantity    The {@code Quantity} is used for default initialization.
	 * @return The created {@code Channel} is returned.
	 */
	public Channel createChannel(String name, Measurement measurement, Quantity quantity) {
		Channel channel = new Channel(createCore(Channel.class));

		// relations
		getCore(channel).getPermanentStore().set(measurement);
		getCore(measurement).getChildrenStore().add(channel);
		getCore(channel).getMutableStore().set(quantity.getDefaultUnit());
		getCore(channel).getMutableStore().set(quantity);

		// properties
		channel.setName(name);
		channel.setDescription(quantity.getDescription());
		channel.setInterpolation(Interpolation.NONE);
		channel.setScalarType(quantity.getDefaultScalarType());
		channel.setRank(quantity.getDefaultRank());
		channel.setTypeSize(quantity.getDefaultTypeSize());

		return channel;
	}

	/**
	 * Creates a new {@link ChannelGroup}.
	 *
	 * @param name           Name of the created {@code ChannelGroup}.
	 * @param numberOfValues The number of values per each related {@link Channel}.
	 * @param measurement    The parent {@link Measurement}.
	 * @return The created {@code ChannelGroup} is returned.
	 * @throws IllegalArgumentException Thrown if numberOfValues is negative.
	 */
	public ChannelGroup createChannelGroup(String name, int numberOfValues, Measurement measurement) {
		if (numberOfValues < 0) {
			throw new IllegalArgumentException("Number of values must be equal or greater than 0.");
		}

		ChannelGroup channelGroup = new ChannelGroup(createCore(ChannelGroup.class));

		// relations
		getCore(channelGroup).getPermanentStore().set(measurement);
		getCore(measurement).getChildrenStore().add(channelGroup);

		// properties
		channelGroup.setName(name);
		channelGroup.setNumberOfValues(Integer.valueOf(numberOfValues));

		return channelGroup;
	}

	/**
	 * Creates a new {@link Measurement}.
	 *
	 * @param name         Name of the created {@code Measurement}.
	 * @param testStep     The parent {@link TestStep}.
	 * @param contextRoots {@link ContextRoot}s containing the descriptive data.
	 * @return The created {@code Measurement} is returned.
	 */
	public Measurement createMeasurement(String name, TestStep testStep, ContextRoot... contextRoots) {
		Measurement measurement = new Measurement(createCore(Measurement.class));

		// relations
		getCore(measurement).getPermanentStore().set(testStep);
		getCore(testStep).getChildrenStore().add(measurement);
		for (ContextRoot contextRoot : contextRoots) {
			getCore(measurement).getMutableStore().set(contextRoot, contextRoot.getContextType());
		}

		// properties
		measurement.setName(name);
		measurement.setDateCreated(LocalDateTime.now());

		return measurement;
	}

	/**
	 * Creates a new {@link Parameter} with initialized with given value.
	 *
	 * @param name         Name of the created {@code Parameter}.
	 * @param value        The value of the created {@code Parameter}.
	 * @param unit         An optionally related {@link Unit}.
	 * @param parameterSet The parent {@link ParameterSet}.
	 * @return The created {@code Parameter} is returned.
	 * @throws IllegalArgumentException Thrown if the {@code ParameterSet} already
	 *                                  contains a {@code Parameter} with given
	 *                                  name.
	 * @see Parameter#setObjectValue(Object, Unit)
	 */
	public Parameter createParameter(String name, Object value, Unit unit, ParameterSet parameterSet) {
		if (parameterSet.getParameter(name).isPresent()) {
			throw new IllegalArgumentException("Parameter with name '" + name + "' already exists.");
		}

		Parameter parameter = new Parameter(createCore(Parameter.class));

		// relations
		getCore(parameter).getPermanentStore().set(parameterSet);
		getCore(parameterSet).getChildrenStore().add(parameter);

		// properties
		parameter.setName(name);
		parameter.setObjectValue(value, unit);

		return parameter;
	}

	/**
	 * Creates a new {@link ParameterSet} for given {@link Measurement}.
	 *
	 * @param name        Name of the created {@code ParameterSet}.
	 * @param version     Version of the created {@code ParameterSet}.
	 * @param measurement The owning {@code Measurement}.
	 * @return The created {@code ParameterSet} is returned.
	 */
	public ParameterSet createParameterSet(String name, String version, Measurement measurement) {
		ParameterSet parameterSet = new ParameterSet(createCore(ParameterSet.class));

		// relations
		getCore(parameterSet).getPermanentStore().set(measurement);
		getCore(measurement).getChildrenStore().add(parameterSet);

		// properties
		parameterSet.setName(name);
		parameterSet.setVersion(version);

		return parameterSet;
	}

	/**
	 * Creates a new {@link ParameterSet} for given {@link Channel}.
	 *
	 * @param name    Name of the created {@code ParameterSet}.
	 * @param version Version of the created {@code ParameterSet}.
	 * @param channel The owning {@code Channel}.
	 * @return The created {@code ParameterSet} is returned.
	 */
	public ParameterSet createParameterSet(String name, String version, Channel channel) {
		ParameterSet parameterSet = new ParameterSet(createCore(ParameterSet.class));

		// relations
		getCore(parameterSet).getPermanentStore().set(channel);
		getCore(channel).getChildrenStore().add(parameterSet);

		// properties
		parameterSet.setName(name);
		parameterSet.setVersion(version);

		return parameterSet;
	}

	/**
	 * Creates a new {@link PhysicalDimension}.
	 *
	 * @param name Name of the created {@code PhysicalDimension}.
	 * @return The created {@code PhysicalDimension} is returned.
	 */
	public PhysicalDimension createPhysicalDimension(String name) {
		PhysicalDimension physicalDimension = new PhysicalDimension(createCore(PhysicalDimension.class));

		// properties
		physicalDimension.setName(name);
		physicalDimension.setLength(Integer.valueOf(0));
		physicalDimension.setMass(Integer.valueOf(0));
		physicalDimension.setTime(Integer.valueOf(0));
		physicalDimension.setTemperature(Integer.valueOf(0));
		physicalDimension.setCurrent(Integer.valueOf(0));
		physicalDimension.setMolarAmount(Integer.valueOf(0));
		physicalDimension.setLuminousIntensity(Integer.valueOf(0));
		physicalDimension.setAngle(Integer.valueOf(0));

		return physicalDimension;
	}

	/**
	 * Creates a new {@link Quantity}.
	 *
	 * @param name        Name of the created {@code Quantity}.
	 * @param defaultUnit The default {@link Unit}.
	 * @return The created {@code Quantity} is returned.
	 */
	public Quantity createQuantity(String name, Unit defaultUnit) {
		Quantity quantity = new Quantity(createCore(Quantity.class));

		// relations
		getCore(quantity).getMutableStore().set(defaultUnit);

		// properties
		quantity.setName(name);
		quantity.setDateCreated(LocalDateTime.now());
		quantity.setDefaultRank(Integer.valueOf(1));
		quantity.setDefaultDimension(new int[] { 0 });
		quantity.setDefaultTypeSize(Integer.valueOf(1));
		quantity.setDefaultChannelName(name);
		quantity.setDefaultScalarType(ScalarType.FLOAT);

		quantity.getValue("Version").set("1");
		quantity.getValue("ValidFlag").set(VersionState.VALID);

		return quantity;
	}

	/**
	 * Creates a new {@link Test} with a reference to the logged in {@link User}, if
	 * there is one.
	 *
	 * @param name Name of the created {@code Test}.
	 * @return The created {@code Test} is returned.
	 */
	public Test createTest(String name) {
		Test test = new Test(createCore(Test.class));

		// relations
		Optional<User> responsiblePerson = getLoggedInUser();
		if (responsiblePerson.isPresent()) {
			// may be null if user entities are not available
			getCore(test).getMutableStore().set(responsiblePerson.get());
		}

		// properties
		test.setName(name);
		test.setDateCreated(LocalDateTime.now());

		return test;
	}

	/**
	 * Creates a new {@link TestStep}.
	 *
	 * @param name Name of the created {@code TestStep}.
	 * @param test The parent {@link Test}.
	 * @return The created {@code TestStep} is returned.
	 */
	public TestStep createTestStep(String name, Test test) {
		TestStep testStep = new TestStep(createCore(TestStep.class));

		// relations
		getCore(testStep).getPermanentStore().set(test);
		getCore(test).getChildrenStore().add(testStep);

		// properties
		testStep.setName(name);
		testStep.setDateCreated(LocalDateTime.now());
		testStep.setOptional(Boolean.TRUE);

		if (test.getID() != null && test.getID().length() > 0) {
			// highest sort index in use will be queried before written
			testStep.setSortIndex(Integer.valueOf(-1));
		} else {
			testStep.setSortIndex(nextIndex(getCore(test).getChildrenStore().get(TestStep.class)));
		}

		return testStep;
	}

	/**
	 * Creates a new {@link Unit}.
	 *
	 * @param name              Name of the created {@code Unit}.
	 * @param physicalDimension The {@link PhysicalDimension}.
	 * @return The created {@code Unit} is returned.
	 */
	public Unit createUnit(String name, PhysicalDimension physicalDimension) {
		Unit unit = new Unit(createCore(Unit.class));

		// relations
		getCore(unit).getMutableStore().set(physicalDimension);

		// properties
		unit.setName(name);
		unit.setOffset(Double.valueOf(0D));
		unit.setFactor(Double.valueOf(1D));

		return unit;
	}

	/**
	 * Creates a new {@link User}.
	 *
	 * @param name      Name of the created {@code User}.
	 * @param givenName Given name of the created {@code User}.
	 * @param surname   Surname of the created {@code User}.
	 * @return The created {@code User} is returned.
	 */
	public User createUser(String name, String givenName, String surname) {
		User user = new User(createCore(User.class));

		// properties
		user.setName(name);
		user.setGivenName(givenName);
		user.setSurname(surname);

		return user;
	}

	// ======================================================================
	// Protected methods
	// ======================================================================

	/**
	 * Creates a new {@link ContextRoot}.
	 *
	 * @param name        Name of the created {@code ContextRoot}.
	 * @param contextType {@link ContextType} of the created {@code ContextRoot}.
	 * @return The created {@code ContextRoot} is returned.
	 */
	protected ContextRoot createContextRoot(String name, ContextType contextType) {
		ContextRoot contextRoot = new ContextRoot(createCore(ContextRoot.class, contextType));

		// properties
		contextRoot.setName(name);
		contextRoot.setVersion(String.valueOf(0));

		return contextRoot;
	}

	/**
	 * Creates a new {@link ContextComponent}.
	 *
	 * @param name        Name of the created {@code ContextComponent}.
	 * @param contextRoot The parent {@link ContextRoot}.
	 * @return The created {@code ContextComponent} is returned.
	 */
	protected ContextComponent createContextComponent(String name, ContextRoot contextRoot) {
		ContextComponent contextComponent = new ContextComponent(createCore(name, ContextComponent.class));

		// relations
		getCore(contextComponent).getPermanentStore().set(contextRoot);
		getCore(contextRoot).getChildrenStore().add(contextComponent);

		// properties
		contextComponent.setName(name);

		return contextComponent;
	}

	/**
	 * Creates a new {@link ContextSensor}.
	 *
	 * @param name             Name of the created {@code ContextSensor}.
	 * @param contextComponent The parent {@link ContextComponent}.
	 * @return The created {@code ContextSensor} is returned.
	 */
	protected ContextSensor createContextSensor(String name, ContextComponent contextComponent) {
		ContextSensor contextSensor = new ContextSensor(createCore(name, ContextSensor.class));
		// relations
		getCore(contextSensor).getPermanentStore().set(contextComponent);
		getCore(contextComponent).getChildrenStore().add(contextSensor);

		// properties
		contextSensor.setName(name);

		return contextSensor;
	}

	/**
	 * Returns the next usable sort index for given {@code List} of
	 * {@link Sortable}s.
	 *
	 * @param sortables The {@code Sortable} whose max sort index will be searched.
	 * @return {@code 1} is returned if given {@code List} is empty, otherwise the
	 *         max sort index increased by 1 is returned.
	 */
	protected static final Integer nextIndex(List<? extends Sortable> sortables) {
		Optional<Integer> maxIndex = sortables.stream().max(Sortable.COMPARATOR).map(Sortable::getSortIndex);
		return Integer.valueOf(maxIndex.isPresent() ? maxIndex.get().intValue() + 1 : 1);
	}

	/**
	 * Returns the {@link ChildrenStore} for given {@link BaseEntity}. Please be
	 * aware that the contents of this store is subject to the adapter creating it.
	 * It is up to the adapter to decide which related entities are included. As
	 * there are adapter specific details to the contents of the store it should be
	 * protected from external access. Therefore by declaring this method protected,
	 * the related functionality is hidden from other classes since the only classes
	 * which can access them (outside this package) are derivatives of
	 * BaseEntityFactory, and it is through such derivatives that BaseEntity's
	 * Stores should be accessed elsewhere if needed.
	 *
	 * @param entity The {@code BaseEntity} whose {@code ChildrenStore} will be
	 *               returned.
	 * @return The {@code ChildrenStore} is returned.
	 */
	protected static ChildrenStore getChildrenStore(BaseEntity entity) {
		return getCore(entity).getChildrenStore();
	}

	/**
	 * Returns the mutable {@link EntityStore} for given {@link BaseEntity}. Please
	 * be aware that the contents of this store is subject to the adapter creating
	 * it. It is up to the adapter to decide which related entities are included. As
	 * there are adapter specific details to the contents of the store it should be
	 * protected from external access. Therefore by declaring this method protected,
	 * the related functionality is hidden from other classes since the only classes
	 * which can access them (outside this package) are derivatives of
	 * BaseEntityFactory, and it is through such derivatives that BaseEntity's
	 * Stores should be accessed elsewhere if needed.
	 * 
	 *
	 * @param entity The {@code BaseEntity} whose {@code ChildrenStore} will be
	 *               returned.
	 * @return The mutable {@code EntityStore} is returned.
	 */
	protected static EntityStore getMutableStore(BaseEntity entity) {
		return getCore(entity).getMutableStore();
	}

	/**
	 * Returns the permanent {@link EntityStore} for given {@link BaseEntity}.
	 * Please be aware that the contents of this store is subject to the adapter
	 * creating it. It is up to the adapter to decide which related entities are
	 * included. As there are adapter specific details to the contents of the store
	 * it should be protected from external access. Therefore by declaring this
	 * method protected, the related functionality is hidden from other classes
	 * since the only classes which can access them (outside this package) are
	 * derivatives of BaseEntityFactory, and it is through such derivatives that
	 * BaseEntity's Stores should be accessed elsewhere if needed.
	 * 
	 * @param entity The {@code BaseEntity} whose {@code ChildrenStore} will be
	 *               returned.
	 * @return The permanent {@code EntityStore} is returned.
	 */
	protected static EntityStore getPermanentStore(BaseEntity entity) {
		return getCore(entity).getPermanentStore();
	}

	/**
	 * Returns {@link Core} of given {@link Entity}. Uses protected method from
	 * BaseEntity, which is accessible here as BaseEntity resides in the same
	 * package as BaseEntityFactory. By declaring this method protected, the
	 * Core-related functionality is hidden from other classes since the only
	 * classes which can access them (outside this package) are derivatives of
	 * BaseEntityFactory, and it is through such derivatives that a BaseEntity's
	 * Core should be accessed elsewhere if needed.
	 *
	 * @param entity The {@code BaseEntity} whose {@code Core} is required.
	 * @return The {@code Core} is returned.
	 */
	protected static final Core getCore(BaseEntity entity) {
		return entity.getCore();
	}

	/**
	 * Create an instance of {@link BaseEntity} (or derivative) with core as the
	 * instance's {@link Core}. By declaring this method protected, the Core-related
	 * functionality is hidden from other classes since the only classes which can
	 * access them (outside this package) are derivatives of BaseEntityFactory, and
	 * it is through such derivatives that a BaseEntity's Core should be accessed
	 * elsewhere if needed. <br>
	 * <br>
	 * This method accesses the (usually protected) Constructor(Core) of clazz, so
	 * this method should be overridden in a derived class and call
	 * super.createBaseEntity() if that constructor is invisible from the derived
	 * class.
	 * 
	 * @param clazz The class to instantiate, must extend {@link BaseEntity}.
	 * @param core  The {@link Core} to use for the newly created instance.
	 * @return The newly created instance.
	 */
	protected <T extends BaseEntity> T createBaseEntity(Class<T> clazz, Core core) {
		try {
			Constructor<T> constructor = clazz.getDeclaredConstructor(Core.class);
			try {
				return constructor.newInstance(core);
			} catch (IllegalAccessException exc) {
				throw new IllegalStateException("Cannot access Constructor(Core) of class '" + clazz.getName() + "'!");
			}
		} catch (NoSuchMethodException | InvocationTargetException | InstantiationException exc) {
			throw new IllegalStateException(exc.getMessage(), exc);
		}
	}

	/**
	 * Returns the {@link User} which is bound to the current session.
	 *
	 * @return {@code Optional} is empty if {@code User} entities do not exist.
	 */
	protected abstract Optional<User> getLoggedInUser();

	/**
	 * Returns a new {@link Core} for given entity class.
	 *
	 * @param <T>         The entity class type.
	 * @param entityClass The entity class.
	 * @return A new {@code Core} instance is returned.
	 */
	protected abstract <T extends Entity> Core createCore(Class<T> entityClass);

	/**
	 * Returns a new {@link Core} for given entity class and {@link ContextType}.
	 *
	 * @param <T>         The entity class type.
	 * @param entityClass The entity class.
	 * @param contextType The {@code ContextType}.
	 * @return A new {@code Core} instance is returned.
	 */
	protected abstract <T extends Entity> Core createCore(Class<T> entityClass, ContextType contextType);

	/**
	 * Returns a new {@link Core} for given entity class and type name.
	 *
	 * @param <T>         The entity class type.
	 * @param name        Name of the entity type.
	 * @param entityClass The entity class.
	 * @return A new {@code Core} instance is returned.
	 */
	protected abstract <T extends Entity> Core createCore(String name, Class<T> entityClass);

}
