package org.eclipse.mdm.api.odsadapter.lookup;

import static java.util.stream.Stream.concat;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.Query;
import org.eclipse.mdm.api.base.query.Record;
import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;

/**
 * Extends {@link EntityRequest} to load children for a given
 * {@link EntityRequest}.
 *
 * @param <T>
 *            The entity type.
 * @since 1.0.0
 * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
 */
final class ChildRequest<T extends Deletable> extends EntityRequest<T> {

	// ======================================================================
	// Instance variables
	// ======================================================================

	private final EntityRequest<?> parent;

	// ======================================================================
	// Constructors
	// ======================================================================

	/**
	 * Constructor.
	 *
	 * @param parentRequest
	 *            The parent {@link EntityRequest}.
	 * @param entityConfig
	 *            The {@link EntityConfig}.
	 */
	ChildRequest(EntityRequest<?> parentRequest, EntityConfig<T> entityConfig) {
		super(parentRequest, entityConfig);
		parent = parentRequest;
	}

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

	/**
	 * Loads all related child entities.
	 *
	 * @return Returns the queried {@code EntityResult}.
	 * @throws DataAccessException
	 *             Thrown if unable to load entities.
	 */
	public EntityResult<T> load() throws DataAccessException {
		filtered = parent.filtered;

		EntityType entityType = entityConfig.getEntityType();
		Relation parentRelation = entityConfig.getEntityType().getRelation(parent.entityConfig.getEntityType());
		Relation reflexiveRelation = entityConfig.isReflexive() ? entityType.getRelation(entityType) : null;

		Query query = modelManager.createQuery()
				// select entity attributes
				.selectAll(entityConfig.getEntityType())
				// select parent entity ID
				.select(parentRelation.getAttribute());

		if (entityConfig.isReflexive()) {
			query.select(reflexiveRelation.getAttribute());
			// entities with children have to be processed before their
			// children!
			query.order(entityType.getIDAttribute());
		}

		// prepare relations select statements
		List<RelationConfig> optionalRelations = selectRelations(query, entityConfig.getOptionalConfigs(), false);
		List<RelationConfig> mandatoryRelations = selectRelations(query, entityConfig.getMandatoryConfigs(), true);
		List<RelationConfig> inheritedRelations = selectRelations(query, entityConfig.getInheritedConfigs(), true);

		// configure filter
		Filter adjustedFilter = Filter.or();
		if (filtered) {
			// preserve current conditions
			adjustedFilter.ids(parentRelation, parent.entityResult.getIDs());
			if (entityConfig.isReflexive()) {
				// extend to retrieve all reflexive child candidates
				adjustedFilter.add(ComparisonOperator.IS_NOT_NULL.create(reflexiveRelation.getAttribute(), 0L));
			}
		}

		// load entities and prepare mappings for required related entities
		List<EntityRecord<?>> parentRecords = new ArrayList<>();
		for (Record record : collectRecords(query.fetch(adjustedFilter))) {
			Optional<String> parentID = record.getID(parentRelation);
			Optional<String> reflexiveParentID = Optional.empty();
			if (entityConfig.isReflexive()) {
				reflexiveParentID = record.getID(reflexiveRelation);
			}
			EntityRecord<T> entityRecord;

			if (parentID.isPresent()) {
				EntityResult<?> parentResult = parent.entityResult;
				@SuppressWarnings({ "unchecked", "rawtypes" })
				Optional<EntityRecord<?>> parentRecord = (Optional) parentResult.get(parentID.get());
				if (!parentRecord.isPresent()) {
					continue;
				}

				entityRecord = entityResult.add(parentRecord.get(), record);
				parentRecords.add(parentRecord.get());
			} else if (entityConfig.isReflexive() && reflexiveParentID.isPresent()) {
				Optional<EntityRecord<T>> parentRecord = entityResult.get(reflexiveParentID.get());
				if (!parentRecord.isPresent()) {
					// this entity's parent was not loaded -> skip
					continue;
				}
				// reflexive child
				entityRecord = entityResult.add(parentRecord.get(), record);
				parentRecords.add(parentRecord.get());
			} else {
				throw new IllegalStateException("Entity without parent found");
			}

			// collect related instance IDs
			concat(concat(optionalRelations.stream(), mandatoryRelations.stream()), inheritedRelations.stream())
					.forEach(rc -> rc.add(entityRecord, record));
		}

		if (entityResult.isEmpty()) {
			// no entities found -> neither related nor child entities required
			return entityResult;
		}

		// load and map related entities
		loadRelatedEntities(optionalRelations);
		loadRelatedEntities(mandatoryRelations);
		assignRelatedEntities(inheritedRelations);

		// sort children of parent
		for (EntityRecord<?> entityRecord : parentRecords) {
			entityRecord.core.getChildrenStore().sort(entityConfig.getEntityClass(), entityConfig.getComparator());
		}

		// load children
		for (EntityConfig<? extends Deletable> childConfig : entityConfig.getChildConfigs()) {
			cache.add(new ChildRequest<>(this, childConfig).load());
		}

		return entityResult;
	}

	// ======================================================================
	// Private methods
	// ======================================================================

	/**
	 * Maps related entities for each given {@link RelationConfig} using the
	 * entities loaded in previous {@link EntityRequest}.
	 *
	 * @param relationConfigs
	 *            The {@code RelationConfig}s.
	 * @throws DataAccessException
	 *             Thrown if unable to load related entities.
	 */
	private void assignRelatedEntities(List<RelationConfig> relationConfigs) throws DataAccessException {
		for (RelationConfig relationConfig : relationConfigs) {
			EntityConfig<?> relatedConfig = relationConfig.entityConfig;

			boolean isContextTypeDefined = entityConfig.getContextType().isPresent();
			for (Entity relatedEntity : cache.get(relatedConfig).getEntities()) {
				boolean setByContextType = !isContextTypeDefined && relatedConfig.getContextType().isPresent();
				List<EntityRecord<?>> entityRecords = relationConfig.dependants.remove(relatedEntity.getID());
				entityRecords = entityRecords == null ? new ArrayList<EntityRecord<?>>() : entityRecords;
				for (EntityRecord<?> entityRecord : entityRecords) {
					setRelatedEntity(entityRecord, relatedEntity,
							setByContextType ? relatedConfig.getContextType().get() : null);
				}
			}

			if (!relationConfig.dependants.isEmpty()) {
				// this may occur if the instance id of the related entity
				// is defined, but the entity itself does not exist
				throw new IllegalStateException("Unable to load related entities.");
			}
		}
	}
}
