/********************************************************************************
 * 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.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.adapter.EntityType;
import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.Query;
import org.eclipse.mdm.api.base.query.Record;
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 = queryService.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.");
			}
		}
	}
}
