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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.mdm.api.base.Transaction;
import org.eclipse.mdm.api.base.massdata.ReadRequest;
import org.eclipse.mdm.api.base.massdata.ReadRequest.ValuesMode;
import org.eclipse.mdm.api.base.massdata.WriteRequest;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.MeasuredValues;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.PhysicalDimension;
import org.eclipse.mdm.api.base.model.Quantity;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.Unit;
import org.eclipse.mdm.api.dflt.ApplicationContext;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.ListMultimap;

public class AtfxExportTask extends AtfxTransferBase implements ApiCopyTask {
	private static final Logger LOG = LoggerFactory.getLogger(AtfxExportTask.class);

	public AtfxExportTask(ApplicationContext src, ApplicationContext dst) {
		super(src, dst);
	}

	@Override
	public void copy(List<? extends Entity> entities) {
		Transaction transaction = entityManagerDst.startTransaction();
		try {
			mapSrcDstEntities.clear();

			ListMultimap<Class<? extends Entity>, Entity> parents = loadParents(entities);
			LOG.trace("Resolved parents: {}", parents);
			supportedRootEntities.forEach(ec -> parents.get(ec).forEach(e -> copyEntity(e, false, transaction)));

			LOG.trace("Export entities: {}", entities);
			entities.forEach(e -> copyEntity(e, true, transaction));

			transaction.commit();
		} catch (Exception exc) {
			try {
				transaction.abort();
			} catch (Exception exc2) {
				LOG.error("Could not abort transaction!");
			}

			throw new ApiCopyException("Could not copy data.", exc);
		}
	}

	private Entity copyEntity(Entity entity, boolean recursive, Transaction transaction) {
		if (entity instanceof Project) {
			return copyProject((Project) entity, recursive, transaction);
		} else if (entity instanceof Pool) {
			return copyPool((Pool) entity, recursive, transaction);
		} else if (entity instanceof Test) {
			return copyTest((Test) entity, recursive, transaction);
		} else if (entity instanceof TestStep) {
			return copyTestStep((TestStep) entity, recursive, transaction);
		} else if (entity instanceof Measurement) {
			return copyMeasurement((Measurement) entity, recursive, transaction);
		} else {
			throw new ApiCopyException("Unsupported entity: '" + entity.getClass().getName() + "'");
		}
	}

	private Project copyProject(Project projectSrc, boolean recursive, Transaction transaction) {
		EntityHolder ehSrc = new EntityHolder(projectSrc, entityManagerSrc);

		EntityHolder ehDst = mapSrcDstEntities.get(ehSrc);

		if (null == ehDst) {
			Project projectDst = entityFactoryDst.createProject(projectSrc.getName());

			copyValues(projectSrc, projectDst, Arrays.asList("Id", "Name"));

			persist(transaction, projectDst);

			ehDst = new EntityHolder(projectDst, entityManagerDst);
			mapSrcDstEntities.put(ehSrc, ehDst);

			if (recursive) {
				entityManagerSrc.loadChildren(projectSrc, Pool.class)
						.forEach(pool -> copyPool(pool, recursive, transaction));
			}
		}

		return (Project) ehDst.getEntity();
	}

	private Pool copyPool(Pool poolSrc, boolean recursive, Transaction transaction) {
		EntityHolder ehSrc = new EntityHolder(poolSrc, entityManagerSrc);

		EntityHolder ehDst = mapSrcDstEntities.get(ehSrc);

		if (null == ehDst) {
			Project projectParentDst = (Project) mapSrcDstEntities
					.get(new EntityHolder(entityManagerSrc.loadParent(poolSrc, Project.class).get(), entityManagerSrc))
					.getEntity();

			Pool poolDst = entityFactoryDst.createPool(poolSrc.getName(), projectParentDst);

			copyValues(poolSrc, poolDst, Arrays.asList("Id", "Name"));

			persist(transaction, poolDst);

			ehDst = new EntityHolder(poolDst, entityManagerDst);
			mapSrcDstEntities.put(ehSrc, ehDst);

			if (recursive) {
				entityManagerSrc.loadChildren(poolSrc, Test.class)
						.forEach(test -> copyTest(test, recursive, transaction));
			}
		}

		return (Pool) ehDst.getEntity();
	}

	private Test copyTest(Test testSrc, boolean recursive, Transaction transaction) {
		EntityHolder ehSrc = new EntityHolder(testSrc, entityManagerSrc);

		EntityHolder ehDst = mapSrcDstEntities.get(ehSrc);

		if (null == ehDst) {
			Pool poolParentDst = (Pool) mapSrcDstEntities
					.get(new EntityHolder(entityManagerSrc.loadParent(testSrc, Pool.class).get(), entityManagerSrc))
					.getEntity();

			Test testDst = entityFactoryDst.createTest(testSrc.getName(), poolParentDst);

			copyValues(testSrc, testDst, Arrays.asList("Id", "Name"));

			persist(transaction, testDst);

			ehDst = new EntityHolder(testDst, entityManagerDst);
			mapSrcDstEntities.put(ehSrc, ehDst);

			if (recursive) {
				entityManagerSrc.loadChildren(testSrc, TestStep.class)
						.forEach(testStep -> copyTestStep(testStep, recursive, transaction));
			}
		}

		return (Test) ehDst.getEntity();
	}

	private TestStep copyTestStep(TestStep testStepSrc, boolean recursive, Transaction transaction) {
		EntityHolder ehSrc = new EntityHolder(testStepSrc, entityManagerSrc);

		EntityHolder ehDst = mapSrcDstEntities.get(ehSrc);

		if (null == ehDst) {
			Test testParentDst = (Test) mapSrcDstEntities
					.get(new EntityHolder(entityManagerSrc.loadParent(testStepSrc, Test.class).get(), entityManagerSrc))
					.getEntity();

			TestStep testStepDst = entityFactoryDst.createTestStep(testStepSrc.getName(), testParentDst);

			copyValues(testStepSrc, testStepDst, Arrays.asList("Id", "Name"));

			persist(transaction, testStepDst);

			ehDst = new EntityHolder(testStepDst, entityManagerDst);
			mapSrcDstEntities.put(ehSrc, ehDst);

			if (recursive) {
				entityManagerSrc.loadChildren(testStepSrc, Measurement.class)
						.forEach(measurement -> copyMeasurement(measurement, recursive, transaction));
			}
		}

		return (TestStep) ehDst.getEntity();
	}

	private Measurement copyMeasurement(Measurement measurementSrc, boolean recursive, Transaction transaction) {
		EntityHolder ehSrc = new EntityHolder(measurementSrc, entityManagerSrc);

		EntityHolder ehDst = mapSrcDstEntities.get(ehSrc);

		if (null == ehDst) {
			TestStep testStepParentDst = (TestStep) mapSrcDstEntities
					.get(new EntityHolder(entityManagerSrc.loadParent(measurementSrc, TestStep.class).get(),
							entityManagerSrc))
					.getEntity();

			Measurement measurementDst = entityFactoryDst.createMeasurement(measurementSrc.getName(),
					testStepParentDst);

			copyValues(measurementSrc, measurementDst, Arrays.asList("Id", "Name"));

			persist(transaction, measurementDst);

			ehDst = new EntityHolder(measurementDst, entityManagerDst);
			mapSrcDstEntities.put(ehSrc, ehDst);

			if (recursive) {
				List<WriteRequest> listWriteRequests = new ArrayList<>();

				Map<String, Channel> mapChannels = new HashMap<>();

				for (Channel channel : entityManagerSrc.loadChildren(measurementSrc, Channel.class)) {
					Channel channelDst = copyChannel(channel, transaction);
					mapChannels.put(channel.getName(), channelDst);
				}

				for (ChannelGroup channelGroup : entityManagerSrc.loadChildren(measurementSrc, ChannelGroup.class)) {
					ChannelGroup channelGroupDst = copyChannelGroup(channelGroup, transaction);

					for (MeasuredValues measuredValues : entityManagerSrc.readMeasuredValues(ReadRequest
							.create(channelGroup).valuesMode(ValuesMode.STORAGE).allChannels().allValues())) {
						if (!mapChannels.containsKey(measuredValues.getName())) {
							throw new ApiCopyException(
									String.format("Cannot find Channel %s in destination!", measuredValues.getName()));
						}

						Channel channelDst = mapChannels.get(measuredValues.getName());

						listWriteRequests.add(createWriteRequest(channelGroupDst, channelDst, measuredValues));
					}
				}

				transaction.writeMeasuredValues(listWriteRequests);
			}
		}

		return (Measurement) ehDst.getEntity();
	}

	private Channel copyChannel(Channel channelSrc, Transaction transaction) {
		EntityHolder ehSrc = new EntityHolder(channelSrc, entityManagerSrc);

		EntityHolder ehDst = mapSrcDstEntities.get(ehSrc);

		if (null == ehDst) {
			Measurement measurementParentDst = (Measurement) mapSrcDstEntities
					.get(new EntityHolder(entityManagerSrc.loadParent(channelSrc, Measurement.class).get(),
							entityManagerSrc))
					.getEntity();

			Quantity quantitySrc = channelSrc.getQuantity();
			Unit unitSrc = quantitySrc.getDefaultUnit();
			PhysicalDimension physicalDimensionSrc = unitSrc.getPhysicalDimension();

			PhysicalDimension physicalDimensionDst = fetchOne(entityManagerDst, PhysicalDimension.class,
					physicalDimensionSrc.getName())
							.orElseGet(() -> entityFactoryDst.createPhysicalDimension(physicalDimensionSrc.getName()));

			if (isNewEntity(physicalDimensionDst)) {
				copyValues(physicalDimensionSrc, physicalDimensionDst, Arrays.asList("Id", "Name"));
				persist(transaction, physicalDimensionDst);
			}

			Unit unitDst = fetchOne(entityManagerDst, Unit.class, unitSrc.getName())
					.orElseGet(() -> entityFactoryDst.createUnit(unitSrc.getName(), physicalDimensionDst));

			if (isNewEntity(unitDst)) {
				copyValues(unitSrc, unitDst, Arrays.asList("Id", "Name"));
				persist(transaction, unitDst);
			}

			Quantity quantityDst = fetchOne(entityManagerDst, Quantity.class, quantitySrc.getName())
					.orElseGet(() -> entityFactoryDst.createQuantity(quantitySrc.getName(), unitDst));

			if (isNewEntity(quantityDst)) {
				copyValues(quantitySrc, quantityDst, Arrays.asList("Id", "Name"));
				persist(transaction, quantityDst);
			}

			Channel channelDst = entityFactoryDst.createChannel(measurementParentDst, quantityDst);

			copyValues(channelSrc, channelDst, Arrays.asList("Id", "Name"));

			persist(transaction, channelDst);

			ehDst = new EntityHolder(channelDst, entityManagerDst);
			mapSrcDstEntities.put(ehSrc, ehDst);
		}

		return (Channel) ehDst.getEntity();
	}

	private ChannelGroup copyChannelGroup(ChannelGroup channelGroupSrc, Transaction transaction) {
		EntityHolder ehSrc = new EntityHolder(channelGroupSrc, entityManagerSrc);

		EntityHolder ehDst = mapSrcDstEntities.get(ehSrc);

		if (null == ehDst) {
			Measurement measurementParentDst = (Measurement) mapSrcDstEntities
					.get(new EntityHolder(entityManagerSrc.loadParent(channelGroupSrc, Measurement.class).get(),
							entityManagerSrc))
					.getEntity();

			ChannelGroup channelGroupDst = entityFactoryDst.createChannelGroup(channelGroupSrc.getName(),
					channelGroupSrc.getNumberOfValues(), measurementParentDst);

			copyValues(channelGroupSrc, channelGroupDst, Arrays.asList("Id", "Name"));

			persist(transaction, channelGroupDst);

			ehDst = new EntityHolder(channelGroupDst, entityManagerDst);
			mapSrcDstEntities.put(ehSrc, ehDst);
		}

		return (ChannelGroup) ehDst.getEntity();
	}

}
