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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.asam.ods.AIDName;
import org.asam.ods.AIDNameUnitId;
import org.asam.ods.AoException;
import org.asam.ods.ApplElemAccess;
import org.asam.ods.ElemResultSetExt;
import org.asam.ods.JoinDef;
import org.asam.ods.NameValueSeqUnitId;
import org.asam.ods.QueryStructureExt;
import org.asam.ods.ResultSetExt;
import org.asam.ods.SelAIDNameUnitId;
import org.asam.ods.SelItem;
import org.asam.ods.SelOrder;
import org.asam.ods.SelValueExt;
import org.asam.ods.T_LONGLONG;
import org.eclipse.mdm.api.base.adapter.Attribute;
import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.Aggregation;
import org.eclipse.mdm.api.base.query.Condition;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.FilterItem;
import org.eclipse.mdm.api.base.query.JoinType;
import org.eclipse.mdm.api.base.query.Query;
import org.eclipse.mdm.api.base.query.Record;
import org.eclipse.mdm.api.base.query.Result;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Strings;

/**
 * ODS implementation of the {@link Query} interface.
 *
 * @since 1.0.0
 * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
 */
public class ODSQuery implements Query {

	// ======================================================================
	// Class variables
	// ======================================================================

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

	private static final String GROUP_NAME = "name";
	private static final String GROUP_AGGRFUNC = "aggrfunc";
	private static final Pattern AGGREGATION_NAME_PATTERN = Pattern
			.compile("(?<" + GROUP_AGGRFUNC + ">\\S+)\\((?<" + GROUP_NAME + ">\\S+)\\)");

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

	private final Map<String, EntityType> entityTypesByID = new HashMap<>();
	private final Set<EntityType> queriedEntityTypes = new HashSet<>();
	private final List<SelAIDNameUnitId> anuSeq = new ArrayList<>();
	private final List<JoinDef> joinSeq = new ArrayList<>();
	private final List<AIDName> groupBy = new ArrayList<>();
	private final List<SelOrder> orderBy = new ArrayList<>();

	private final ApplElemAccess applElemAccess;

	private int limit;

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

	/**
	 * Constructor.
	 *
	 * @param applElemAccess Used to execute the query.
	 */
	ODSQuery(ApplElemAccess applElemAccess) {
		this.applElemAccess = applElemAccess;
		limit = 0;
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isQueried(EntityType entityType) {
		return queriedEntityTypes.contains(entityType);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Query limit(int limit) {
		this.limit = limit;
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Query select(Attribute attribute, Aggregation aggregation) {
		EntityType entityType = attribute.getEntityType();
		entityTypesByID.put(Long.toString(ODSConverter.fromODSLong(((ODSEntityType) entityType).getODSID())),
				entityType);
		queriedEntityTypes.add(entityType);
		anuSeq.add(createSelect(attribute, aggregation));
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Query join(Relation relation, JoinType join) {
		queriedEntityTypes.add(relation.getSource());
		queriedEntityTypes.add(relation.getTarget());
		joinSeq.add(createJoin(relation, join));
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Query group(List<Attribute> attributes) {
		for (Attribute attribute : attributes) {
			group(attribute);
		}
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Query group(Attribute attribute) {
		groupBy.add(createAIDName(attribute));
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Query order(Attribute attribute, boolean ascending) {
		orderBy.add(createOrderBy(attribute, ascending));
		return this;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Optional<Result> fetchSingleton(Filter filter) throws DataAccessException {
		List<Result> results = fetch(filter);
		if (results.isEmpty()) {
			return Optional.empty();
		} else if (results.size() > 1) {
			throw new DataAccessException("Multiple results found after executing the singleton query!");
		}

		return Optional.of(results.get(0));
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Result> fetch(Filter filter) throws DataAccessException {
		try {

			List<SelItem> condSeq = new ArrayList<>();
			int condCount = 0;
			for (FilterItem conditionItem : filter) {
				SelItem selItem = new SelItem();
				if (conditionItem.isCondition()) {
					selItem.value(createCondition(conditionItem.getCondition()));
				} else if (conditionItem.isBracketOperator()) {
					selItem._operator(ODSUtils.BRACKETOPERATORS.get(conditionItem.getBracketOperator()));
				} else if (conditionItem.isBooleanOperator()) {
					selItem._operator(ODSUtils.OPERATORS.get(conditionItem.getBooleanOperator()));
					condCount++;
				} else {
					throw new IllegalArgumentException("Passed filter item is neither an operator nor a condition.");
				}

				condSeq.add(selItem);
			}

			QueryStructureExt qse = new QueryStructureExt();
			qse.anuSeq = anuSeq.toArray(new SelAIDNameUnitId[anuSeq.size()]);
			qse.condSeq = condSeq.toArray(new SelItem[condSeq.size()]);
			qse.groupBy = groupBy.toArray(new AIDName[groupBy.size()]);
			qse.joinSeq = joinSeq.toArray(new JoinDef[joinSeq.size()]);
			qse.orderBy = orderBy.toArray(new SelOrder[orderBy.size()]);

			List<Result> results = new ArrayList<>();
			long start = System.currentTimeMillis();
			for (Result result : new ResultFactory(entityTypesByID, applElemAccess.getInstancesExt(qse, limit)[0])) {
				results.add(result);
			}
			long stop = System.currentTimeMillis();

			LOGGER.debug("Query executed in {} ms and retrieved {} result rows ({} selections, {} conditions, "
					+ "{} joins).", stop - start, results.size(), anuSeq.size(), condCount, joinSeq.size());
			return results;
		} catch (AoException aoe) {
			throw new DataAccessException(aoe.reason, aoe);
		}
	}

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

	/**
	 * Converts given {@link Attribute} and {@link Aggregation} to an ODS
	 * {@link SelAIDNameUnitId}.
	 *
	 * @param attribute   The {@code Attribute}.
	 * @param aggregation The {@code Aggregation}.
	 * @return The corresponding {@code SelAIDNameUnitId} is returned.
	 */
	private SelAIDNameUnitId createSelect(Attribute attribute, Aggregation aggregation) {
		SelAIDNameUnitId sanu = new SelAIDNameUnitId();

		sanu.aggregate = ODSUtils.AGGREGATIONS.get(aggregation);
		sanu.attr = createAIDName(attribute);
		sanu.unitId = new T_LONGLONG();

		return sanu;
	}

	/**
	 * Converts given {@link Condition} to an ODS {@link SelValueExt}.
	 *
	 * @param condition The {@code Condition}.
	 * @return The corresponding {@code SelValueExt} is returned.
	 * @throws DataAccessException Thrown in case of errors.
	 */
	private SelValueExt createCondition(Condition condition) throws DataAccessException {
		SelValueExt sve = new SelValueExt();

		sve.oper = ODSUtils.OPERATIONS.get(condition.getComparisonOperator());
		sve.attr = new AIDNameUnitId();
		sve.attr.unitId = new T_LONGLONG();
		sve.attr.attr = createAIDName(condition.getAttribute());
		sve.value = ODSConverter.toODSValue(condition.getAttribute(), condition.getValue());

		return sve;
	}

	/**
	 * Converts given {@link Relation} and {@link JoinType} to an ODS
	 * {@link JoinDef}.
	 *
	 * @param relation The {@code Relation}.
	 * @param join     The {@code JoinType}.
	 * @return The corresponding {@code JoinDef} is returned.
	 */
	private JoinDef createJoin(Relation relation, JoinType join) {
		JoinDef joinDef = new JoinDef();

		joinDef.fromAID = ((ODSEntityType) relation.getSource()).getODSID();
		joinDef.toAID = ((ODSEntityType) relation.getTarget()).getODSID();
		joinDef.refName = relation.getName();
		joinDef.joiningType = ODSUtils.JOINS.get(join);

		return joinDef;
	}

	/**
	 * Converts given {@link Attribute} and sort order flag to an ODS
	 * {@link SelOrder}.
	 *
	 * @param attribute The {@code Attribute}.
	 * @param ascending The sort order.
	 * @return The corresponding {@code SelOrder} is returned.
	 */
	private SelOrder createOrderBy(Attribute attribute, boolean ascending) {
		SelOrder selOrder = new SelOrder();

		selOrder.attr = createAIDName(attribute);
		selOrder.ascending = ascending;

		return selOrder;
	}

	/**
	 * Converts given {@link Attribute} to an ODS {@link AIDName}.
	 *
	 * @param attribute The {@code Attribute}.
	 * @return The corresponding {@code AIDName} is returned.
	 */
	private AIDName createAIDName(Attribute attribute) {
		AIDName aidName = new AIDName();

		aidName.aid = ((ODSEntityType) attribute.getEntityType()).getODSID();
		aidName.aaName = attribute.getName();

		return aidName;
	}

	private static Aggregation getAggregation(String odsAggrFunc) {
		switch (Strings.nullToEmpty(odsAggrFunc).trim().toUpperCase()) {
		case "COUNT":
			return Aggregation.COUNT;
		case "DCOUNT":
			return Aggregation.DISTINCT_COUNT;
		case "MIN":
			return Aggregation.MINIMUM;
		case "MAX":
			return Aggregation.MAXIMUM;
		case "AVG":
			return Aggregation.AVERAGE;
		case "STDDEV":
			return Aggregation.DEVIATION;
		case "SUM":
			return Aggregation.SUM;
		case "DISTINCT":
			return Aggregation.DISTINCT;
		default:
			throw new IllegalArgumentException(
					"Unsupported aggregate function '" + Strings.nullToEmpty(odsAggrFunc).trim().toUpperCase() + "'!");
		}

	}

	// ======================================================================
	// Inner classes
	// ======================================================================

	/**
	 * Traverses the ODS {@link ResultSetExt} and creates a {@link Result} for each
	 * row.
	 */
	private static final class ResultFactory implements Iterable<Result>, Iterator<Result> {

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

		private final List<RecordFactory> recordFactories = new ArrayList<>();
		private final int length;
		private int index;

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

		/**
		 * Constructor.
		 *
		 * @param entityTypes  Used to access {@link EntityType} by its ODS ID.
		 * @param resultSetExt The ODS values sequence containers.
		 * @throws DataAccessException Thrown on conversion errors.
		 */
		public ResultFactory(Map<String, EntityType> entityTypes, ResultSetExt resultSetExt)
				throws DataAccessException {
			for (ElemResultSetExt elemResultSetExt : resultSetExt.firstElems) {
				EntityType entityType = entityTypes.get(Long.toString(ODSConverter.fromODSLong(elemResultSetExt.aid)));
				recordFactories.add(new RecordFactory(entityType, elemResultSetExt.values));
			}

			length = recordFactories.isEmpty() ? 0 : recordFactories.get(0).getLength();
		}

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

		/**
		 * {@inheritDoc}
		 */
		@Override
		public boolean hasNext() {
			return index < length;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Result next() {
			if (!hasNext()) {
				throw new NoSuchElementException("No such element available.");
			}
			Result result = new Result();

			for (RecordFactory recordFactory : recordFactories) {
				result.addRecord(recordFactory.createRecord(index));
			}

			index++;
			return result;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Iterator<Result> iterator() {
			return this;
		}

	}

	/**
	 * Creates a {@link Record} for given index from the original ODS values
	 * sequence for a given {@link EntityType}.
	 */
	private static final class RecordFactory {

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

		private final List<ValueFactory> valueFactories = new ArrayList<>();
		private final EntityType entityType;

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

		/**
		 * Constructor.
		 *
		 * @param entityType The associated {@link EntityType}.
		 * @param nvsuis     The ODS value sequence containers.
		 * @throws DataAccessException Thrown on conversion errors.
		 */
		private RecordFactory(EntityType entityType, NameValueSeqUnitId[] nvsuis) throws DataAccessException {
			this.entityType = entityType;
			for (NameValueSeqUnitId nvsui : nvsuis) {
				String attributeName = nvsui.valName;
				Aggregation aggregation = Aggregation.NONE;
				Matcher matcher = AGGREGATION_NAME_PATTERN.matcher(nvsui.valName);
				if (matcher.matches()) {
					attributeName = matcher.group(GROUP_NAME);
					aggregation = ODSQuery.getAggregation(matcher.group(GROUP_AGGRFUNC));
				}

				valueFactories.add(new ValueFactory(entityType.getAttribute(attributeName), aggregation, nvsui));
			}
		}

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

		private int getLength() {
			return valueFactories.isEmpty() ? 0 : valueFactories.get(0).getLength();
		}

		private Record createRecord(int index) {
			Record record = new Record(entityType);
			for (ValueFactory valueFactory : valueFactories) {
				record.addValue(valueFactory.createValue(index));
			}

			return record;
		}

	}

	/**
	 * Creates a {@link Value} container for given index from the original ODS value
	 * sequence for a given {@link Attribute}.
	 */
	private static final class ValueFactory {

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

		private final List<Value> values;
		private final String unit;
		private final int length;

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

		/**
		 * Constructor.
		 *
		 * @param attribute The associated {@link Attribute}.
		 * @param nvsui     The ODS value sequence container.
		 * @throws DataAccessException Thrown on conversion errors.
		 */
		private ValueFactory(Attribute attribute, Aggregation aggregation, NameValueSeqUnitId nvsui)
				throws DataAccessException {
			length = nvsui.value.flag.length;
			unit = attribute.getUnit();
			values = ODSConverter.fromODSValueSeq(attribute, aggregation, unit, nvsui.value);
		}

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

		/**
		 * Returns the length of the sequence.
		 *
		 * @return Length of the sequence is returned.
		 */
		private int getLength() {
			return length;
		}

		/**
		 * Returns the {@link Value} for given index.
		 *
		 * @param index Index within the sequence.
		 * @return The corresponding {@code Value} is returned.
		 */
		private Value createValue(int index) {
			return values.get(index);
		}

	}

}
