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

import org.asam.ods.AIDName;
import org.asam.ods.AIDNameValueSeqUnitId;
import org.asam.ods.AoException;
import org.asam.ods.AoSession;
import org.asam.ods.ApplicationElement;
import org.asam.ods.ApplicationStructure;
import org.asam.ods.DataType;
import org.asam.ods.ElemId;
import org.asam.ods.InstanceElementIterator;
import org.asam.ods.TS_Union;
import org.asam.ods.TS_UnionSeq;
import org.asam.ods.TS_Value;
import org.asam.ods.TS_ValueSeq;
import org.asam.ods.T_LONGLONG;
import org.eclipse.mdm.api.base.ServiceNotProvidedException;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.dflt.ApplicationContext;
import org.eclipse.mdm.api.dflt.EntityManager;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.odsadapter.ODSContext;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Creates Classification instances, because openMDM4 clients checks them and
 * does not show any data if classifications are absent. As soon as
 * Classification can be created through standard MDM5 API this class becomes
 * obsolete.
 */
public class ClassificationUtil {
	private static final Logger LOG = LoggerFactory.getLogger(ClassificationUtil.class);

	private ApplicationContext contextDst;
	private EntityManager entityManagerDst;

	public ClassificationUtil(ApplicationContext contextDst) {
		this.contextDst = contextDst;

		entityManagerDst = contextDst.getEntityManager()
				.orElseThrow(() -> new ServiceNotProvidedException(EntityManager.class));
	}

	public void attachClassification(List<Entity> listEntities) {
		if (!(contextDst instanceof ODSContext)) {
			LOG.debug("Cannot attach classification as destination is not an ODS storage!");

			return;
		}

		AoSession aoSession = ((ODSContext) contextDst).getAoSession();

		try {
			aoSession.startTransaction();
		} catch (AoException exc) {
			LOG.error(exc.getMessage(), exc);

			return;
		}

		try {
			ApplicationStructure applicationStructure = aoSession.getApplicationStructure();
			ApplicationElement aeDomain = applicationStructure.getElementByName("Domain");
			ApplicationElement aeProjectDomain = applicationStructure.getElementByName("ProjectDomain");
			ApplicationElement aeStatus = applicationStructure.getElementByName("Status");
			ApplicationElement aeClassification = applicationStructure.getElementByName("Classification");

			if (null == aeDomain) {
				throw new IllegalStateException("Cannot find application element Domain in destination!");
			}

			if (null == aeProjectDomain) {
				throw new IllegalStateException("Cannot find application element ProjectDomain in destination!");
			}

			if (null == aeStatus) {
				throw new IllegalStateException("Cannot find application element Status in destination!");
			}

			if (null == aeClassification) {
				throw new IllegalStateException("Cannot find application element Classification in destination!");
			}

			InstanceElementIterator iter = aeDomain.getInstances("*");

			if (iter.getCount() != 1) {
				throw new IllegalStateException("No or more than one Domain instance found in destination!");
			}

			T_LONGLONG iidDomain = iter.nextN(1)[0].getId();

			iter = aeStatus.getInstances("Imported");

			if (iter.getCount() != 1) {
				throw new IllegalStateException(
						"No or more than one Status instance with name \"Imported\" found in destination!");
			}

			T_LONGLONG iidStatus = iter.nextN(1)[0].getId();

			for (Entity entity : listEntities) {
				Project rootProject = null;

				if (entity instanceof Test) {
					rootProject = entityManagerDst
							.loadParent(entityManagerDst.loadParent(entity, Pool.class).get(), Project.class).get();
				} else if (entity instanceof TestStep) {
					rootProject = entityManagerDst.loadParent(entityManagerDst
							.loadParent(entityManagerDst.loadParent(entity, Test.class).get(), Pool.class).get(),
							Project.class).get();
				} else {
					continue;
				}

				String rootProjectName = rootProject.getName();

				T_LONGLONG iidProjectDomain = null;

				iter = aeProjectDomain.getInstances(rootProject.getName());

				switch (iter.getCount()) {
				case 0: {
					T_LONGLONG aidProjectDomain = aeProjectDomain.getId();
					List<AIDNameValueSeqUnitId> listProjectDomainAnvsuis = new ArrayList<>();
					listProjectDomainAnvsuis.add(createAnvsui(aidProjectDomain, "Name", rootProjectName));
					listProjectDomainAnvsuis
							.add(createAnvsui(aidProjectDomain, "MimeType", "application/x-asam.aoany.projectdomain"));

					ElemId[] elemIds = aoSession.getApplElemAccess().insertInstances(listProjectDomainAnvsuis
							.toArray(new AIDNameValueSeqUnitId[listProjectDomainAnvsuis.size()]));

					if (elemIds.length == 1) {
						iidProjectDomain = elemIds[0].iid;
					} else {
						throw new IllegalStateException(String.format(
								"Could not create ProjectDomain instance with name \"%s\" in destination!",
								rootProjectName));
					}
				}
					break;
				case 1: {
					iidProjectDomain = iter.nextN(1)[0].getId();
				}
					break;
				default:
					throw new IllegalStateException(
							String.format("More than one ProjectDomain instance with name \"%s\" found in destination!",
									rootProjectName));
				}

				T_LONGLONG iidClassification = null;

				String classificationName = String.format("ProjDomainId_%d.DomainId_%d.StatusId_%d",
						ODSConverter.fromODSLong(iidProjectDomain), ODSConverter.fromODSLong(iidDomain),
						ODSConverter.fromODSLong(iidStatus));

				iter = aeClassification.getInstances(classificationName);

				if (iter.getCount() > 0) {
					iidClassification = iter.nextN(1)[0].getId();
				}

				if (null == iidClassification) {
					T_LONGLONG aidClassification = aeClassification.getId();
					AIDNameValueSeqUnitId[] arrAnvsuis = new AIDNameValueSeqUnitId[5];
					arrAnvsuis[0] = createAnvsui(aidClassification, "Name", classificationName);
					arrAnvsuis[1] = createAnvsui(aidClassification, "MimeType",
							"application/x-asam.aoany.classification");
					arrAnvsuis[2] = createAnvsui(aidClassification, "Domain", iidDomain);
					arrAnvsuis[3] = createAnvsui(aidClassification, "Status", iidStatus);
					arrAnvsuis[4] = createAnvsui(aidClassification, "ProjectDomain", iidProjectDomain);

					ElemId[] elemIds = aoSession.getApplElemAccess().insertInstances(arrAnvsuis);

					if (elemIds.length == 1) {
						iidClassification = elemIds[0].iid;
					} else {
						throw new IllegalStateException(String.format(
								"Could not create Classification instance with name \"%s\" in destination!",
								classificationName));
					}
				}

				if (null != iidClassification) {
					ApplicationElement aeEntity = applicationStructure.getElementByName(entity.getTypeName());

					if (null == aeEntity) {
						throw new IllegalStateException(String.format(
								"Could not find application element \"%s\" in destination!", entity.getTypeName()));
					}

					T_LONGLONG aidEntity = aeEntity.getId();
					AIDNameValueSeqUnitId[] arrEntityAnvsuis = new AIDNameValueSeqUnitId[2];
					arrEntityAnvsuis[0] = createAnvsui(aidEntity, "Id",
							ODSConverter.toODSLong(Long.valueOf(entity.getID())));
					arrEntityAnvsuis[1] = createAnvsui(aidEntity, "Classification", iidClassification);

					aoSession.getApplElemAccess().updateInstances(arrEntityAnvsuis);
				} else {
					throw new IllegalStateException(
							String.format("No Classification instance with name \"%s\" available in destination!",
									classificationName));
				}
			}

			aoSession.commitTransaction();
		} catch (AoException exc) {
			try {
				LOG.error(exc.getMessage(), exc);

				aoSession.abortTransaction();
			} catch (AoException exc2) {
				LOG.error(exc2.getMessage(), exc2);
			}
		}
	}

	private AIDNameValueSeqUnitId createAnvsui(T_LONGLONG aid, String attrName, String value) throws AoException {
		AIDNameValueSeqUnitId anvsui = new AIDNameValueSeqUnitId();
		anvsui.attr = new AIDName(aid, attrName);
		anvsui.unitId = new T_LONGLONG(0, 0);
		anvsui.values = tsValue2tsValueSeq(getTSValue(value));

		return anvsui;
	}

	private AIDNameValueSeqUnitId createAnvsui(T_LONGLONG aid, String attrName, T_LONGLONG value) throws AoException {
		AIDNameValueSeqUnitId anvsui = new AIDNameValueSeqUnitId();
		anvsui.attr = new AIDName(aid, attrName);
		anvsui.unitId = new T_LONGLONG(0, 0);
		anvsui.values = tsValue2tsValueSeq(getTSValue(value));

		return anvsui;
	}

	public static TS_ValueSeq tsValue2tsValueSeq(TS_Value value) throws AoException {
		TS_ValueSeq vSeq = new TS_ValueSeq();
		vSeq.flag = new short[] { value.flag };
		vSeq.u = new TS_UnionSeq();
		DataType dt = value.u.discriminator();
		if (dt == DataType.DT_STRING) {
			vSeq.u.stringVal(new String[] { value.u.stringVal() });
		} else if (dt == DataType.DT_LONGLONG) {
			vSeq.u.longlongVal(new T_LONGLONG[] { value.u.longlongVal() });
		}
		return vSeq;
	}

	private TS_Value getTSValue(T_LONGLONG value) {
		TS_Value v = new TS_Value();
		v.flag = 15;
		v.u = new TS_Union();
		v.u.longlongVal(value);
		return v;
	}

	private TS_Value getTSValue(String value) {
		TS_Value v = new TS_Value();
		v.u = new TS_Union();
		if (value == null || value.length() < 1) {
			v.flag = 0;
			v.u.stringVal("");
		} else {
			v.flag = 15;
			v.u.stringVal(value);
		}
		return v;
	}
}
