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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.asam.ods.AoException;
import org.asam.ods.Column;
import org.asam.ods.ElemId;
import org.asam.ods.NameValueSeqUnit;
import org.asam.ods.T_LONGLONG;
import org.asam.ods.ValueMatrix;
import org.asam.ods.ValueMatrixMode;
import org.eclipse.mdm.api.base.adapter.Attribute;
import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.massdata.ReadRequest;
import org.eclipse.mdm.api.base.massdata.ReadRequest.ValuesMode;
import org.eclipse.mdm.api.base.model.AxisType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.MeasuredValues;
import org.eclipse.mdm.api.base.model.SequenceRepresentation;
import org.eclipse.mdm.api.base.model.Unit;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.base.query.Filter;
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.odsadapter.query.ODSEntityType;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;

import com.google.common.collect.Lists;

/**
 * Reads mass data specified in {@link ReadRequest}s.
 *
 * @since 1.0.0
 * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
 */
public final class ReadRequestHandler {
	public static final class ColumnAttributes {
		private String name;
		private SequenceRepresentation sequenceRepresentation;
		private double[] generationParameters;
		private boolean independent;
		private AxisType axisType;

		public ColumnAttributes(String name, SequenceRepresentation sequenceRepresentation,
				double[] generationParameters, boolean independent, AxisType axisType) {
			this.name = name;
			this.sequenceRepresentation = sequenceRepresentation;
			this.generationParameters = generationParameters;
			this.independent = independent;
			this.axisType = axisType;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public SequenceRepresentation getSequenceRepresentation() {
			return sequenceRepresentation;
		}

		public void setSequenceRepresentation(SequenceRepresentation sequenceRepresentation) {
			this.sequenceRepresentation = sequenceRepresentation;
		}

		public double[] getGenerationParameters() {
			return generationParameters;
		}

		public void setGenerationParameters(double[] generationParameters) {
			this.generationParameters = generationParameters;
		}

		public boolean isIndependentColumn() {
			return independent;
		}

		public void setIndependentColumn(boolean independent) {
			this.independent = independent;
		}

		public AxisType getAxisType() {
			return axisType;
		}

		public void setAxisType(AxisType axisType) {
			this.axisType = axisType;
		}

	}

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

	private final ODSModelManager modelManager;
	private final QueryService queryService;

	// ======================================================================
	// Constructors
	// ======================================================================

	/**
	 * Constructor.
	 *
	 * @param modelManager Used to gain access to value matrices.
	 */
	public ReadRequestHandler(ODSModelManager modelManager, QueryService queryService) {
		this.modelManager = modelManager;
		this.queryService = queryService;
	}

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

	/**
	 * Loads {@link MeasuredValues} as defined in given {@link ReadRequest}.
	 *
	 * @param readRequest The {@code MeasuredValues} request configuration.
	 * @return The loaded {@code MeasuredValues} are returned.
	 * @throws DataAccessException Thrown if unable to load {@code
	 * 		MeasuredValues}     .
	 */
	public List<MeasuredValues> execute(ReadRequest readRequest) throws DataAccessException {
		ValueMatrix valueMatrix = null;
		Column[] arrColumns = null;

		try {
			valueMatrix = getValueMatrix(readRequest);
			List<Pair<Column, ColumnAttributes>> listColumnPairs = getODSColumns(readRequest, valueMatrix);

			arrColumns = listColumnPairs.stream().map(Pair::getLeft).toArray(Column[]::new);
			ColumnAttributes[] arrColumnAttributes = listColumnPairs.stream().map(Pair::getRight)
					.toArray(ColumnAttributes[]::new);

			NameValueSeqUnit[] nvsus = valueMatrix.getValue(arrColumns, readRequest.getStartIndex(),
					readRequest.getRequestSize());
			return ODSConverter.fromODSMeasuredValuesSeq(nvsus, arrColumnAttributes);
		} catch (AoException aoe) {
			throw new DataAccessException(aoe.reason, aoe);
		} finally {
			releaseColumns(arrColumns);
			releaseValueMatrix(valueMatrix);
		}
	}

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

	/**
	 * Loads all for each defined {@link Channel} in given {@link ReadRequest} and
	 * loads the corresponding {@link Column} using given {@link ValueMatrix}.
	 *
	 * @param readRequest Defines required {@code Column}s.
	 * @param valueMatrix Used to load required {@code Column}s.
	 * @return {@code Column} configured in given {@code ReadRequest} are returned
	 *         with defined {@link Unit} setup.
	 * @throws AoException         Throw if unable to load all available
	 *                             {@code Column}s.
	 * @throws DataAccessException Thrown on wrong {@code ReadRequest} setup.
	 */
	private List<Pair<Column, ColumnAttributes>> getODSColumns(ReadRequest readRequest, ValueMatrix valueMatrix)
			throws AoException, DataAccessException {
		List<Pair<Column, ColumnAttributes>> listColumnPairs = new ArrayList<>();
		Map<String, Column> mapColumns = new HashMap<>();

		try {
			if (readRequest.isLoadAllChannels()) {
				// TODO should it be possible to overwrite the unit of some
				// channels?!
				// -> this results in a performance issue since we need to call
				// getName()
				// on each column for mapping! (no longer, see below!)
				Column[] columns = valueMatrix.getColumns("*");

				if (null != columns) {
					for (Column column : columns) {
						String columnName = column.getName();
						if (mapColumns.containsKey(columnName)) {
							releaseColumns(columns);
							throw new DataAccessException(
									String.format("Duplicate column name '%s' found within submatrix ID %d!",
											columnName, Long.valueOf(readRequest.getChannelGroup().getID())));
						}

						mapColumns.put(columnName, column);
					}
				}
			} else {
				for (Entry<Channel, Unit> entry : readRequest.getChannels().entrySet()) {
					Channel channel = entry.getKey();
					Unit unit = entry.getValue();
					String channelName = channel.getName();
					Column[] columns = valueMatrix.getColumns(channelName);
					if (columns == null || columns.length != 1) {
						releaseColumns(columns);
						throw new DataAccessException(String.format(
								"Zero or more than one column with name '%s' found within submatrix ID %d!",
								channelName, Long.valueOf(readRequest.getChannelGroup().getID())));
					}

					Column column = columns[0];
					if (!unit.nameEquals(channel.getUnit().getName())) {
						column.setUnit(unit.getName());
					}

					mapColumns.put(channelName, column);
				}
			}

			if (mapColumns.size() > 0) {
				EntityType localColumnEntityType = modelManager.getEntityType("LocalColumn");
				Attribute idAttr = localColumnEntityType.getAttribute("Id");
				Attribute nameAttr = localColumnEntityType.getAttribute("Name");
				Attribute submatrixAttr = localColumnEntityType.getAttribute("SubMatrix");

				// Don't query GenerationParameters together with other non-ID attributes as
				// Avalon dislikes this:
				Query query1 = queryService.createQuery()
						.select(Lists.newArrayList(idAttr, nameAttr,
								localColumnEntityType.getAttribute("SequenceRepresentation"),
								localColumnEntityType.getAttribute("IndependentFlag"),
								localColumnEntityType.getAttribute("axistype")));

				Filter filter = Filter.and().add(ComparisonOperator.EQUAL.create(submatrixAttr,
						Long.valueOf(readRequest.getChannelGroup().getID())));

				Set<String> setColumnNames = mapColumns.keySet();

				Map<String, ColumnAttributes> mapColumnAttributes = new HashMap<>();

				for (Result result : query1.fetch(filter)) {
					Map<String, Value> mapValues = result.getRecord(localColumnEntityType).getValues();

					String columnName = mapValues.get("Name").extract();

					if (setColumnNames.contains(columnName)) {
						ColumnAttributes ca = new ColumnAttributes(columnName,
								(ValuesMode.CALCULATED == readRequest.getValuesMode() ? SequenceRepresentation.EXPLICIT
										: mapValues.get("SequenceRepresentation").extract()),
								new double[0], ((short) mapValues.get("IndependentFlag").extract() != 0),
								mapValues.get("axistype").extract());

						mapColumnAttributes.put(mapValues.get("Id").extract(), ca);
					}
				}

				if (ValuesMode.CALCULATED != readRequest.getValuesMode()) {
					Query query2 = queryService.createQuery().select(idAttr,
							localColumnEntityType.getAttribute("GenerationParameters"));

					for (Result result : query2.fetch(filter)) {
						Map<String, Value> mapValues = result.getRecord(localColumnEntityType).getValues();

						ColumnAttributes ca = mapColumnAttributes.get(mapValues.get("Id").extract());

						if (ca != null) {
							ca.setGenerationParameters(mapValues.get("GenerationParameters").extract());
						}
					}
				}

				for (Map.Entry<String, ColumnAttributes> me : mapColumnAttributes.entrySet()) {
					ColumnAttributes ca = me.getValue();
					listColumnPairs.add(new ImmutablePair<Column, ColumnAttributes>(mapColumns.get(ca.getName()), ca));
				}
			}

			return listColumnPairs;
		} catch (AoException e) {
			releaseColumns(listColumnPairs.stream().map(Pair::getLeft).toArray(Column[]::new));
			throw new DataAccessException("Unable to load column due to: " + e.reason, e);
		}
	}

	/**
	 * Returns the {@link ValueMatrix} CORBA service object associated with given
	 * {@link ReadRequest}.
	 *
	 * @param readRequest The {@code ReadRequest}.
	 * @return The {@code ValueMatrix} is returned.
	 * @throws AoException Thrown if unable to load the {@code ValueMatrix}.
	 */
	private ValueMatrix getValueMatrix(ReadRequest readRequest) throws AoException {
		Entity entity = readRequest.getChannelGroup();
		T_LONGLONG iid = ODSConverter.toODSID(entity.getID());
		T_LONGLONG aid = ((ODSEntityType) modelManager.getEntityType(entity)).getODSID();
		ValueMatrixMode valueMatrixMode = ValueMatrixMode.CALCULATED;
		switch (readRequest.getValuesMode()) {
		case CALCULATED:
			valueMatrixMode = ValueMatrixMode.CALCULATED;
			break;
		case STORAGE:
			valueMatrixMode = ValueMatrixMode.STORAGE;
			break;
		default:
			throw new DataAccessException(
					String.format("Unsupported ValueMode %s!", readRequest.getValuesMode().name()));
		}

		return modelManager.getApplElemAccess().getValueMatrixInMode(new ElemId(aid, iid), valueMatrixMode);
	}

	/**
	 * Releases given {@link ValueMatrix} CORBA object.
	 *
	 * @param valueMatrix Will be released.
	 */
	private void releaseValueMatrix(ValueMatrix valueMatrix) {
		if (valueMatrix == null) {
			return;
		}

		try {
			valueMatrix.destroy();
		} catch (AoException aoe) {
			// ignore
		} finally {
			valueMatrix._release();
		}
	}

	/**
	 * Releases each CORBA {@link Column} object.
	 *
	 * @param columns Will be released.
	 */
	private void releaseColumns(Column[] columns) {
		if (columns == null) {
			return;
		}

		for (Column column : columns) {
			try {
				column.destroy();
			} catch (AoException e) {
				// ignore
			} catch (Exception e) {
				// ignore
			} finally {
				column._release();
			}
		}
	}

}
