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

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.reducing;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.eclipse.mdm.api.base.adapter.Attribute;
import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.ContextRoot;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.Aggregation;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.FilterItem;
import org.eclipse.mdm.api.base.query.JoinType;
import org.eclipse.mdm.api.base.query.Query;
import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.base.query.Result;
import org.eclipse.mdm.api.base.search.ContextState;
import org.eclipse.mdm.api.base.search.SearchQuery;
import org.eclipse.mdm.api.base.search.Searchable;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.eclipse.mdm.api.odsadapter.search.JoinTree.JoinConfig;
import org.eclipse.mdm.api.odsadapter.search.JoinTree.JoinNode;

/**
 * Base implementation for entity {@link SearchQuery}.
 *
 * @since 1.0.0
 * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
 */
abstract class BaseEntitySearchQuery implements SearchQuery {

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

	private final Class<? extends Entity> rootEntityClass;
	private final JoinTree joinTree = new JoinTree();
	private final Class<? extends Entity> entityClass;

	private final ODSModelManager modelManager;
	private final QueryService queryService;
	// ======================================================================
	// Constructors
	// ======================================================================

	/**
	 * Constructor.
	 *
	 * @param modelManager    Used to load {@link EntityType}s.
	 * @param entityClass     The source entity class of this search query.
	 * @param rootEntityClass The root entity class of this search query.
	 */
	protected BaseEntitySearchQuery(ODSModelManager modelManager, QueryService queryService,
			Class<? extends Entity> entityClass, Class<? extends Entity> rootEntityClass) {
		this.modelManager = modelManager;
		this.queryService = queryService;
		this.entityClass = entityClass;
		this.rootEntityClass = rootEntityClass;

		EntityConfig<?> entityConfig = modelManager.getEntityConfig(new Key<>(entityClass));
		EntityType source = entityConfig.getEntityType();

		entityConfig.getOptionalConfigs().stream().map(EntityConfig::getEntityType)
				.filter(et -> !"Classification".equals(et.getName())).forEach(entityType -> {
					joinTree.addNode(source, entityType, true, JoinType.OUTER);
				});

		entityConfig.getMandatoryConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
			joinTree.addNode(source, entityType, true, JoinType.INNER);
		});
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<EntityType> listEntityTypes() {
		return joinTree.getNodeNames().stream().map(modelManager::getEntityType).collect(Collectors.toList());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Searchable getSearchableRoot() {
		Function<String, SearchableNode> factory = k -> {
			return new SearchableNode(modelManager.getEntityType(k));
		};

		Map<String, SearchableNode> nodes = new HashMap<>();
		for (Entry<String, List<String>> entry : joinTree.getTree().entrySet()) {
			SearchableNode parent = nodes.computeIfAbsent(entry.getKey(), factory);

			for (String childName : entry.getValue()) {
				parent.addRelated(nodes.computeIfAbsent(childName, factory));
			}
		}

		return nodes.get(modelManager.getEntityType(rootEntityClass).getName());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Value> getFilterValues(Attribute attribute, Filter filter) throws DataAccessException {
		Query query = queryService.createQuery().select(attribute, Aggregation.DISTINCT).group(attribute);

		// add required joins
		filter.stream().filter(FilterItem::isCondition).map(FilterItem::getCondition).forEach(c -> {
			addJoins(query, c.getAttribute().getEntityType());
		});

		addImplicitLocalColumnJoin(query);

		return query.fetch(filter).stream().map(r -> r.getValue(attribute, Aggregation.DISTINCT))
				.collect(Collectors.toList());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Result> getFilterResults(List<Attribute> attributes, Filter filter, ContextState contextState) throws DataAccessException {
		Query query = queryService.createQuery();
		for (Attribute attribute : attributes) {
			addJoins(query, attribute.getEntityType());
			query.select(attribute, Aggregation.DISTINCT);
			query.group(attribute);
		}

		// add required joins
		filter.stream().filter(FilterItem::isCondition).map(FilterItem::getCondition).forEach(c -> {
			addJoins(query, c.getAttribute().getEntityType());
		});

		addImplicitLocalColumnJoin(query);

		return query.fetch(filter);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Result> fetchComplete(List<EntityType> entityTypes, Filter filter) throws DataAccessException {
		Query query = queryService.createQuery().selectID(modelManager.getEntityType(entityClass));

		// add required joins
		entityTypes.stream().forEach(entityType -> {
			addJoins(query, entityType);
			query.selectAll(entityType);
		});

		return fetch(query, filter);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Result> fetch(List<Attribute> attributes, Filter filter) throws DataAccessException {
		Query query = queryService.createQuery().selectID(modelManager.getEntityType(entityClass));

		// add required joins
		attributes.stream().forEach(attribute -> {
			addJoins(query, attribute.getEntityType());
			query.select(attribute);
		});

		return fetch(query, filter);
	}

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

	/**
	 * Adds given {@link JoinConfig} to the internally managed {@link JoinTree}.
	 *
	 * @param joinConfig Will be added.
	 */
	protected final void addJoinConfig(JoinConfig joinConfig) {
		EntityConfig<?> targetEntityConfig = modelManager.getEntityConfig(new Key<>(joinConfig.target));
		EntityType target = targetEntityConfig.getEntityType();

		// add dependency source to target
		joinTree.addNode(modelManager.getEntityType(joinConfig.source), target, joinConfig.viaParent, JoinType.INNER);

		// add target's optional dependencies
		targetEntityConfig.getOptionalConfigs().stream().map(EntityConfig::getEntityType)
				.filter(et -> !"Classification".equals(et.getName())).forEach(entityType -> {
					joinTree.addNode(target, entityType, true, JoinType.OUTER);
				});

		// add target's mandatory dependencies
		targetEntityConfig.getMandatoryConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
			joinTree.addNode(target, entityType, true, JoinType.INNER);
		});
	}

	/**
	 * Adds JoinConfig for LocalColumn.
	 */
	protected final void addChannelOverLocalColumnJoinConfig() {
		EntityType etLocalColumn = modelManager.getEntityType("LocalColumn");
		EntityType etChannel = modelManager.getEntityType(Channel.class);
		EntityType etChannelGroup = modelManager.getEntityType(ChannelGroup.class);

		joinTree.addNode(etChannelGroup, etLocalColumn, false, JoinType.INNER);
		joinTree.addNode(etLocalColumn, etChannel, false, JoinType.INNER);
	}

	/**
	 * Adds JoinConfig for LocalColumn.
	 */
	protected final void addChannelGroupOverLocalColumnJoinConfig() {
		EntityType etLocalColumn = modelManager.getEntityType("LocalColumn");
		EntityType etChannel = modelManager.getEntityType(Channel.class);
		EntityType etChannelGroup = modelManager.getEntityType(ChannelGroup.class);

		joinTree.addNode(etLocalColumn, etChannelGroup, false, JoinType.INNER);
		joinTree.addNode(etChannel, etLocalColumn, false, JoinType.INNER);
	}

	/**
	 * Adds joins to context data according to the given {@link ContextState}.
	 *
	 * @param contextState The {@code ContextState}.
	 */
	protected final void addJoinConfig(ContextState contextState) {
		if (contextState == null) {
			// nothing to do
			return;
		}

		Class<? extends Entity> source = contextState.isOrdered() ? TestStep.class : Measurement.class;
		for (ContextType contextType : ContextType.values()) {
			EntityType rootEntityType = modelManager.getEntityType(ContextRoot.class, contextType);
			for (Relation componentRelation : rootEntityType.getChildRelations()) {
				joinTree.addNode(componentRelation.getSource(), componentRelation.getTarget(), true, JoinType.OUTER);

				for (Relation sensorRelation : componentRelation.getTarget().getChildRelations()) {
					joinTree.addNode(sensorRelation.getSource(), sensorRelation.getTarget(), true, JoinType.OUTER);
				}
			}

			joinTree.addNode(modelManager.getEntityType(source), rootEntityType, true, JoinType.OUTER);
		}
	}

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

	/**
	 * Executes given {@link Query} using given {@link Filter}. Joins required for
	 * the given {@code Filter} will be implicitly added as needed.
	 *
	 * @param query  Will be executed.
	 * @param filter The query filtering sequence.
	 * @return Returns the {@link Result}s in a {@code List}.
	 * @throws DataAccessException Thrown if failed to execute given {@code Query}.
	 */
	private List<Result> fetch(Query query, Filter filter) throws DataAccessException {
		filter.stream().filter(FilterItem::isCondition).map(FilterItem::getCondition)
				.forEach(c -> addJoins(query, c.getAttribute().getEntityType()));

		addImplicitLocalColumnJoin(query);

		EntityType entityType = modelManager.getEntityType(entityClass);
		return query.order(entityType.getIDAttribute()).fetch(filter).stream()
				// group by instance ID and merge grouped results
				.collect(groupingBy(r -> r.getRecord(entityType).getID(), reducing(Result::merge)))
				// collect merged results
				.values().stream().filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
	}

	/**
	 * Adds join statements to given target {@link EntityType} as needed to be able
	 * to execute given {@code Query}.
	 *
	 * @param query      The {@link Query}.
	 * @param entityType The target {@link EntityType}.
	 */
	private void addJoins(Query query, EntityType entityType) {
		EntityType searchQueryEntityType = modelManager.getEntityType(entityClass);
		if (query.isQueried(entityType) || entityType.equals(searchQueryEntityType)) {
			return;
		}

		JoinNode joinNode = joinTree.getJoinNode(entityType.getName());
		EntityType sourceEntityType = modelManager.getEntityType(joinNode.source);
		addJoins(query, sourceEntityType);
		query.join(sourceEntityType.getRelation(entityType), joinNode.joinType);
	}

	/**
	 * If SubMatrix and MeaQuantity are queried, they are joined over MeaResult, but
	 * they must be additionally joined over LocalColumn. This method checks if
	 * SubMatrix and MeaQuantity are queried and adds joins to LocalColumn to the
	 * given query if not already added.
	 * 
	 * @param query query to check and modify
	 */
	private void addImplicitLocalColumnJoin(Query query) {
		EntityType etLocalColumn = modelManager.getEntityType("LocalColumn");
		EntityType etChannelGroup = modelManager.getEntityType(ChannelGroup.class);
		EntityType etChannel = modelManager.getEntityType(Channel.class);

		if (joinTree.getNodeNames().contains("LocalColumn") && query.isQueried(etChannelGroup)
				&& query.isQueried(etChannel)) {
			query.join(etChannelGroup, etLocalColumn);
			query.join(etLocalColumn, etChannel);
		}
	}

}
