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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.asam.ods.AoException;
import org.asam.ods.ApplicationStructure;
import org.asam.ods.ElemId;
import org.asam.ods.InstanceElement;
import org.asam.ods.T_LONGLONG;
import org.eclipse.mdm.api.atfxadapter.transaction.ATFXTransaction;
import org.eclipse.mdm.api.base.ServiceNotProvidedException;
import org.eclipse.mdm.api.base.Transaction;
import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.massdata.ReadRequest;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.ContextDescribable;
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.Environment;
import org.eclipse.mdm.api.base.model.MeasuredValues;
import org.eclipse.mdm.api.base.model.StatusAttachable;
import org.eclipse.mdm.api.base.model.User;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.base.query.Filter;
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.Record;
import org.eclipse.mdm.api.base.query.Result;
import org.eclipse.mdm.api.dflt.EntityManager;
import org.eclipse.mdm.api.dflt.model.Classification;
import org.eclipse.mdm.api.dflt.model.Status;
import org.eclipse.mdm.api.odsadapter.ODSContext;
import org.eclipse.mdm.api.odsadapter.ODSContextFactory;
import org.eclipse.mdm.api.odsadapter.ODSEntityManager;
import org.eclipse.mdm.api.odsadapter.ReadRequestHandler;
import org.eclipse.mdm.api.odsadapter.lookup.EntityLoader;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Strings;

/**
 * ASAM ODS implementation of the {@link EntityManager} interface.
 *
 * @see ODSEntityManager
 */
public class ATFXEntityManager implements EntityManager {
	private static final Logger LOGGER = LoggerFactory.getLogger(ATFXEntityManager.class);

	private final ATFXContext context;
	private final ODSModelManager odsModelManager;
	private final QueryService queryService;
	private final EntityLoader entityLoader;

	/**
	 * Constructor.
	 *
	 * @param context The {@link ODSContext}.
	 */
	public ATFXEntityManager(ATFXContext context) {
		this.context = context;
		this.odsModelManager = context.getODSModelManager();
		this.queryService = context.getQueryService()
				.orElseThrow(() -> new ServiceNotProvidedException(QueryService.class));
		entityLoader = new EntityLoader(odsModelManager, queryService);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Environment loadEnvironment() throws DataAccessException {
		List<Environment> environments = loadAll(Environment.class);
		if (environments.size() != 1) {
			throw new DataAccessException("Unable to laod the environment entity.");
		}

		return environments.get(0);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Optional<User> loadLoggedOnUser() throws DataAccessException {
		return Optional.empty();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public <T extends Entity> List<T> load(Class<T> entityClass, Collection<String> instanceIDs)
			throws DataAccessException {
		return entityLoader.loadAll(new Key<>(entityClass), instanceIDs);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public <T extends Entity> List<T> load(Class<T> entityClass, ContextType contextType,
			Collection<String> instanceIDs) throws DataAccessException {
		return entityLoader.loadAll(new Key<>(entityClass, contextType), instanceIDs);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public <T extends Entity> Optional<T> loadParent(Entity child, Class<T> entityClass) throws DataAccessException {
		EntityType parentEntityType = odsModelManager.getEntityType(entityClass);
		EntityType childEntityType = odsModelManager.getEntityType(child);

		Optional<String> instanceID = Optional.empty();

		if (child instanceof Channel && ChannelGroup.class.equals(entityClass)) {
			// this covers the gap between channel and channel group via local column
			EntityType localColumnEntityType = odsModelManager.getEntityType("LocalColumn");

			Relation relLocalColumnToChannel = localColumnEntityType.getRelation(childEntityType);
			Relation relLocalColumnToChannelGroup = localColumnEntityType.getRelation(parentEntityType);

			Optional<String> localColumnID = queryService.createQuery().select(localColumnEntityType.getIDAttribute())
					.fetchSingleton(Filter.idOnly(relLocalColumnToChannel, child.getID()))
					.map(r -> r.getRecord(localColumnEntityType)).map(r -> r.getID());

			if (localColumnID.isPresent()) {
				instanceID = queryService.createQuery().select(relLocalColumnToChannelGroup.getAttribute())
						.fetchSingleton(Filter.idOnly(localColumnEntityType, localColumnID.get()))
						.map(r -> r.getRecord(localColumnEntityType))
						.map(r -> r.getID(relLocalColumnToChannelGroup).get());
			}
		} else {
			Relation relationToParent = childEntityType.getRelation(parentEntityType);

			Query query = queryService.createQuery().select(relationToParent.getAttribute());
			instanceID = query.fetchSingleton(Filter.idOnly(childEntityType, child.getID()))
					.map(r -> r.getRecord(childEntityType)).map(r -> r.getID(relationToParent).get());
		}

		if (instanceID.isPresent()) {
			return Optional.of(entityLoader.load(new Key<>(entityClass), instanceID.get()));
		}

		return Optional.empty();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public <T extends Entity> List<T> loadAll(Class<T> entityClass, String pattern) throws DataAccessException {
		return entityLoader.loadAll(new Key<>(entityClass), pattern);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public <T extends StatusAttachable> List<T> loadAll(Class<T> entityClass, Status status, String pattern)
			throws DataAccessException {
		EntityType entityType = odsModelManager.getEntityType(entityClass);
		EntityType classificationType = odsModelManager.getEntityType(Classification.class);
		EntityType statusEntityType = odsModelManager.getEntityType(status.getTypeName());

		List<String> instanceIDs = queryService.createQuery().join(entityType, classificationType)
				.join(classificationType, statusEntityType).selectID(entityType)
				.fetch(Filter.and().id(statusEntityType, status.getID()).name(entityType, pattern)).stream()
				.map(r -> r.getRecord(entityType)).map(Record::getID).collect(Collectors.toList());

		return entityLoader.loadAll(new Key<>(entityClass), instanceIDs);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public <T extends Entity> List<T> loadAll(Class<T> entityClass, ContextType contextType, String pattern)
			throws DataAccessException {
		return entityLoader.loadAll(new Key<>(entityClass, contextType), pattern);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public <T extends Entity> List<T> loadChildren(Entity parent, Class<T> entityClass, String pattern)
			throws DataAccessException {
		if (!Strings.isNullOrEmpty(pattern) && !"*".equals(pattern)) {
			throw new DataAccessException("Pattern not supported by ATFXAdapter");
		}
		EntityType parentEntityType = odsModelManager.getEntityType(parent);
		EntityType childEntityType = odsModelManager.getEntityType(entityClass);

		List<String> instanceIDs;

		if (parent instanceof ChannelGroup && Channel.class.equals(entityClass)) {
			// this covers the gap between channel and channel group via local column
			EntityType localColumnEntityType = odsModelManager.getEntityType("LocalColumn");

			Relation relLocalColumnToChannel = localColumnEntityType.getRelation(childEntityType);
			Relation relLocalColumnToChannelGroup = localColumnEntityType.getRelation(parentEntityType);

			instanceIDs = queryService.createQuery().select(relLocalColumnToChannel.getAttribute())
					.fetch(Filter.and().id(relLocalColumnToChannelGroup, parent.getID()).name(localColumnEntityType,
							pattern))
					.stream().map(r -> r.getRecord(localColumnEntityType))
					.map(r -> r.getID(relLocalColumnToChannel).get()).collect(Collectors.toList());

			return entityLoader.loadAll(new Key<>(entityClass), instanceIDs);
		} else {
			Relation relationToParent = childEntityType.getRelation(parentEntityType);

			instanceIDs = queryService.createQuery().selectID(childEntityType).select(relationToParent.getAttribute())
					.fetch(Filter.and().id(relationToParent, parent.getID()).name(childEntityType, pattern)).stream()
					.map(r -> r.getRecord(childEntityType)).map(Record::getID).collect(Collectors.toList());
		}

		return entityLoader.loadAll(new Key<>(entityClass), instanceIDs);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ContextType> loadContextTypes(ContextDescribable contextDescribable) throws DataAccessException {
		EntityType contextDescribableEntityType = odsModelManager.getEntityType(contextDescribable);
		Query query = queryService.createQuery();

		Map<ContextType, EntityType> contextRootEntityTypes = new EnumMap<>(ContextType.class);
		for (ContextType contextType : ContextType.values()) {
			EntityType entityType = odsModelManager.getEntityType(ContextRoot.class, contextType);
			contextRootEntityTypes.put(contextType, entityType);
			query.join(contextDescribableEntityType.getRelation(entityType), JoinType.OUTER).selectID(entityType);
		}

		Optional<Result> result = query
				.fetchSingleton(Filter.idOnly(contextDescribableEntityType, contextDescribable.getID()));
		if (result.isPresent()) {
			List<ContextType> contextTypes = new ArrayList<>();
			for (Entry<ContextType, EntityType> entry : contextRootEntityTypes.entrySet()) {
				Optional<String> instanceID = result.map(r -> r.getRecord(entry.getValue())).map(Record::getID);
				if (instanceID.isPresent()) {
					contextTypes.add(entry.getKey());
				}
			}

			return contextTypes;
		}

		return Collections.emptyList();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Map<ContextType, ContextRoot> loadContexts(ContextDescribable contextDescribable,
			ContextType... contextTypes) throws DataAccessException {
		EntityType contextDescribableEntityType = odsModelManager.getEntityType(contextDescribable);

		Map<ContextType, EntityType> contextRootEntityTypes = new EnumMap<>(ContextType.class);
		Map<ContextType, ContextRoot> contextRoots = new EnumMap<>(ContextType.class);
		for (ContextType contextType : contextTypes.length == 0 ? ContextType.values() : contextTypes) {

			EntityType entityType = odsModelManager.getEntityType(ContextRoot.class, contextType);
			contextRootEntityTypes.put(contextType, entityType);

			// openATFX does not support joins in queries, thus we have to retrive the
			// ContextRoots one by one by ID
			ElemId elemId = new ElemId(((ODSEntityType) contextDescribableEntityType).getODSID(),
					ODSConverter.toODSID(contextDescribable.getID()));
			try {
				T_LONGLONG[] contextRootIds = odsModelManager.getApplElemAccess().getRelInst(elemId,
						contextDescribableEntityType.getRelation(entityType).getName());

				if (contextRootIds != null && contextRootIds.length > 0) {
					// There can only be one result per ContextType, thus we take the first one and
					// ignore the rest
					String instanceID = Long.toString(ODSConverter.fromODSLong(contextRootIds[0]));

					contextRoots.put(contextType,
							entityLoader.load(new Key<>(ContextRoot.class, contextType), instanceID));
				}
			} catch (AoException e) {
				throw new DataAccessException("Cannot load contextRoot '" + entityType.getName() + "' for ID '"
						+ contextDescribable.getID() + "': " + e.reason, e);
			}
		}
		return contextRoots;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<MeasuredValues> readMeasuredValues(ReadRequest readRequest) throws DataAccessException {
		return new ReadRequestHandler(odsModelManager, queryService).execute(readRequest);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Transaction startTransaction() throws DataAccessException {
		try {
			return new ATFXTransaction(context);
		} catch (AoException e) {
			throw new DataAccessException("Unable to start transaction due to: " + e.reason, e);
		}
	}

	/**
	 * Retrives the ASAM paths for the given entities. The ASAM paths are prefixed
	 * with a servicename, in the form
	 * <code>corbaloc:[iop|ssliop]:1.2@HOSTNAME:PORT/NameService/MDM.ASAM-ODS/</code>
	 * 
	 * @returns returns a map with the ASAM paths to the given entities. If a entity
	 *          is not found in the ODS server the entity is not included in the
	 *          result map.
	 * @throws DataAccessException      if links could not be loaded for the given
	 *                                  entities
	 * @throws IllegalArgumentException if a the source or typeName of an entity is
	 *                                  invalid
	 * @see org.eclipse.mdm.api.base.BaseEntityManager#getLinks(Collection)
	 */
	@Override
	public Map<Entity, String> getLinks(Collection<Entity> entities) throws DataAccessException {

		Map<Entity, String> linkMap = new HashMap<>();

		ApplicationStructure appStructure;
		try {
			appStructure = odsModelManager.getAoSession().getApplicationStructure();
		} catch (AoException e) {
			throw new DataAccessException("Could not load application structure! Reason: " + e.reason, e);
		}

		String serverRoot = context.getParameters().get(ODSContextFactory.PARAM_NAMESERVICE) + "/"
				+ context.getParameters().get(ODSContextFactory.PARAM_SERVICENAME);

		Map<String, List<Entity>> entitiesByTypeName = entities.stream().filter(e -> e.getTypeName() != null)
				.collect(Collectors.groupingBy(Entity::getTypeName));

		for (Map.Entry<String, List<Entity>> entry : entitiesByTypeName.entrySet()) {
			ODSEntityType et = (ODSEntityType) odsModelManager.getEntityType(entry.getKey());

			List<ElemId> elemIds = entry.getValue().stream()
					.map(e -> new ElemId(et.getODSID(), ODSConverter.toODSLong(Long.parseLong(e.getID()))))
					.collect(Collectors.toList());

			try {
				InstanceElement[] instances = appStructure.getInstancesById(elemIds.toArray(new ElemId[0]));

				for (InstanceElement ie : instances) {
					String id = Long.toString(ODSConverter.fromODSLong(ie.getId()));
					String asamPath = serverRoot + ie.getAsamPath();
					entry.getValue().stream().filter(e -> e.getID().equals(id)).findFirst()
							.ifPresent(e -> linkMap.put(e, asamPath));
				}
			} catch (AoException e) {
				LOGGER.debug("Could not load links for entities: " + entities + ". Reason: " + e.reason, e);
			}
		}

		return linkMap;
	}

	/**
	 * {@inheritDoc}
	 */
	public <T extends Entity> List<T> loadRelatedEntities(Entity entity, String relationName, Class<T> relatedClass) {
		ODSEntityType entityType = ((ODSEntityType) context.getODSModelManager().getEntityType(entity));
		ElemId elemId = new ElemId(entityType.getODSID(), ODSConverter.toODSID(entity.getID()));

		try {
			T_LONGLONG[] instanceIds = context.getAoSession().getApplElemAccess().getRelInst(elemId, relationName);
			List<String> instanceIDs = Stream.of(instanceIds).map(ODSConverter::fromODSLong).map(Object::toString)
					.collect(Collectors.toList());
			return entityLoader.loadAll(new Key<>(relatedClass), instanceIDs);
		} catch (AoException e) {
			throw new DataAccessException("Cannot load related instances: " + e.reason, e);
		}
	}
}
