/********************************************************************************
 * 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.atfxadapter.transaction;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import org.asam.ods.AIDName;
import org.asam.ods.AIDNameValueSeqUnitId;
import org.asam.ods.AoException;
import org.asam.ods.T_LONGLONG;
import org.eclipse.mdm.api.base.adapter.Attribute;
import org.eclipse.mdm.api.base.adapter.Core;
import org.eclipse.mdm.api.base.adapter.EntityStore;
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.model.FileLink;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Insert statement is used to update entities and their children.
 *
 * @see org.eclipse.mdm.api.odsadapter.transaction.UpdateStatement
 */
final class UpdateStatement extends BaseStatement {

	private static final Logger LOGGER = LoggerFactory.getLogger(UpdateStatement.class);

	private final Map<Class<? extends Entity>, List<Entity>> childrenToCreate = new HashMap<>();
	private final Map<Class<? extends Entity>, List<Entity>> childrenToUpdate = new HashMap<>();
	private final Map<Class<? extends Deletable>, List<Deletable>> childrenToRemove = new HashMap<>();
	private Map<String, List<Value>> updateMap = new HashMap<>();

	private final List<String> nonUpdatableRelationNames;
	private final boolean ignoreChildren;

	/**
	 * Constructor.
	 *
	 * @param transaction    The owning {@link ATFXTransaction}.
	 * @param entityType     The associated {@link EntityType}.
	 * @param ignoreChildren If {@code true}, then child entities won't be
	 *                       processed.
	 */
	UpdateStatement(ATFXTransaction transaction, EntityType entityType, boolean ignoreChildren) {
		super(transaction, entityType);

		nonUpdatableRelationNames = entityType.getInfoRelations().stream().map(Relation::getName)
				.collect(Collectors.toList());
		this.ignoreChildren = ignoreChildren;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void execute(Collection<Entity> entities) throws AoException, DataAccessException, IOException {
		for (Entity entity : entities) {
			readEntityCore(ODSEntityFactory.extract(entity));
		}

		// TODO tracing progress in this method...

		List<AIDNameValueSeqUnitId> anvsuList = new ArrayList<>();
		T_LONGLONG aID = getEntityType().getODSID();

		for (Entry<String, List<Value>> entry : updateMap.entrySet()) {
			if (nonUpdatableRelationNames.contains(entry.getKey())) {
				// skip "empty" informative relation sequence
				continue;
			}

			Attribute attribute = getEntityType().getAttribute(entry.getKey());

			AIDNameValueSeqUnitId anvsu = new AIDNameValueSeqUnitId();
			anvsu.attr = new AIDName(aID, entry.getKey());
			anvsu.unitId = ODSConverter.toODSLong(0);
			anvsu.values = ODSConverter.toODSValueSeq(attribute, entry.getValue());
			anvsuList.add(anvsu);
		}

		long start = System.currentTimeMillis();
		getApplElemAccess().updateInstances(anvsuList.toArray(new AIDNameValueSeqUnitId[anvsuList.size()]));
		long stop = System.currentTimeMillis();

		LOGGER.debug("{} " + getEntityType() + " instances updated in {} ms.", entities.size(), stop - start);

		// delete first to make sure naming collisions do not occur!
		for (List<Deletable> children : childrenToRemove.values()) {
			getTransaction().delete(children);
		}
		for (List<Entity> children : childrenToCreate.values()) {
			getTransaction().create(children);
		}
		for (List<Entity> children : childrenToUpdate.values()) {
			getTransaction().update(children);
		}
	}

	/**
	 * Reads given {@link Core} and prepares its data to be written:
	 *
	 * <ul>
	 * <li>collect new and removed {@link FileLink}s</li>
	 * <li>collect property {@link Value}s</li>
	 * <li>collect foreign key {@code Value}s</li>
	 * <li>collect child entities for recursive create/update/delete</li>
	 * </ul>
	 *
	 * @param core The {@code Core}.
	 * @throws DataAccessException Thrown in case of errors.
	 */
	private void readEntityCore(Core core) throws DataAccessException {
		if (!core.getTypeName().equals(getEntityType().getName())) {
			throw new IllegalArgumentException("Entity core '" + core.getTypeName()
					+ "' is incompatible with current update statement for entity type '" + getEntityType() + "'.");
		}

		// add all entity values
		for (Value value : core.getAllValues().values()) {
			updateMap.computeIfAbsent(value.getName(), k -> new ArrayList<>()).add(value);
		}

		updateMap.computeIfAbsent(getEntityType().getIDAttribute().getName(), k -> new ArrayList<>())
				.add(getEntityType().getIDAttribute().createValue(core.getID()));

		// define "empty" values for ALL informative relations
		for (Relation relation : getEntityType().getInfoRelations()) {
			updateMap.computeIfAbsent(relation.getName(), k -> new ArrayList<>()).add(relation.createValue());
		}

		// preserve "empty" relation values for removed related entities
		EntityStore mutableStore = core.getMutableStore();
		mutableStore.getRemoved().stream().map(e -> getModelManager().getEntityType(e))
				.map(getEntityType()::getRelation).map(Relation::getName).forEach(nonUpdatableRelationNames::remove);

		// replace "empty" relation values with corresponding instance IDs
		setRelationIDs(mutableStore.getCurrent());

		collectChildEntities(core);

		getTransaction().addModified(core);
	}

	/**
	 * Collects child entities for recursive processing.
	 *
	 * @param core The {@link Core}.
	 */
	private void collectChildEntities(Core core) {
		if (ignoreChildren) {
			return;
		}

		for (Entry<Class<? extends Deletable>, List<? extends Deletable>> entry : core.getChildrenStore().getCurrent()
				.entrySet()) {
			Map<Boolean, List<Entity>> partition = entry.getValue().stream()
					.collect(Collectors.partitioningBy(e -> ODSUtils.isValidID(e.getID())));
			List<Entity> virtualEntities = partition.get(Boolean.FALSE);
			if (virtualEntities != null && !virtualEntities.isEmpty()) {
				childrenToCreate.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()).addAll(virtualEntities);
			}
			List<Entity> existingEntities = partition.get(Boolean.TRUE);
			if (existingEntities != null && !existingEntities.isEmpty()) {
				childrenToUpdate.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()).addAll(existingEntities);
			}
		}

		for (Entry<Class<? extends Deletable>, List<? extends Deletable>> entry : core.getChildrenStore().getRemoved()
				.entrySet()) {
			List<Deletable> toDelete = entry.getValue().stream().filter(e -> ODSUtils.isValidID(e.getID()))
					.collect(Collectors.toList());
			childrenToRemove.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()).addAll(toDelete);
		}
	}

	/**
	 * Overwrites empty foreign key {@link Value} containers.
	 *
	 * @param relatedEntities The related {@link Entity}s.
	 */
	private void setRelationIDs(Collection<Entity> relatedEntities) {
		for (Entity relatedEntity : relatedEntities) {
			if (!ODSUtils.isValidID(relatedEntity.getID())) {
				throw new IllegalArgumentException("Related entity must be a persited entity.");
			}

			Relation relation = getEntityType().getRelation(getModelManager().getEntityType(relatedEntity));
			List<Value> relationValues = updateMap.get(relation.getName());
			if (relationValues == null) {
				throw new IllegalStateException("Relation '" + relation
						+ "' is incompatible with update statement for entity type '" + getEntityType() + "'");
			}
			relationValues.get(relationValues.size() - 1).set(relatedEntity.getID());
			nonUpdatableRelationNames.remove(relation.getName());
		}
	}

}
