/********************************************************************************
 * 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.businessobjects.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import org.eclipse.mdm.protobuf.Mdm;
import org.eclipse.mdm.protobuf.Mdm.DateArray;
import org.eclipse.mdm.protobuf.Mdm.DoubleArray;
import org.eclipse.mdm.protobuf.Mdm.MeasuredValues;
import org.eclipse.mdm.protobuf.Mdm.MeasuredValues.Builder;
import org.eclipse.mdm.protobuf.Mdm.PreviewValuesList;
import org.eclipse.mdm.protobuf.Mdm.ScalarType;

import com.google.common.primitives.Bytes;
import com.google.common.primitives.Ints;
import com.google.protobuf.Timestamp;

/**
 * Helper class to calculate preview values.
 *
 */
public class PreviewHelper {
	/**
	 * Calcluates the preview values for numerical datatypes. For non numberical
	 * datatypes an empty MeasuredValues object is returned.
	 * 
	 * @param measuredValues List of measuredValues containing the mass data for the
	 *                       preview.
	 * @param numberOfChunks number of requested chunks for the preview
	 * @return calculated preview values
	 */
	public PreviewValuesList calculatePreview(List<MeasuredValues> measuredValues, int numberOfChunks) {
		return measuredValues.stream().map(mv -> calculatePreview(mv, numberOfChunks))
				.reduce(Mdm.PreviewValuesList.newBuilder(), (pl1, pl2) -> {
					pl1.addAllMin(pl2.getMinList());
					pl1.addAllMax(pl2.getMaxList());
					pl1.addAllAvg(pl2.getAvgList());
					return pl1;
				}).build();
	}

	/**
	 * Calculate preview for one {@link MeasuredValues}
	 * 
	 * @param measuredValues measured values
	 * @param numberOfChunks number of chunks
	 * @return a builder with the preview values set
	 */
	protected Mdm.PreviewValuesList.Builder calculatePreview(Mdm.MeasuredValues measuredValues, int numberOfChunks) {
		Mdm.MeasuredValues.Builder mv = Mdm.MeasuredValues.newBuilder(measuredValues).setScalarType(ScalarType.DOUBLE);

		switch (mv.getValuesCase()) {
		case BOOLEAN_ARRAY:
			return createEmpty(mv.clearBooleanArray());
		case BYTE_ARRAY:
			byte[] bytes = measuredValues.getByteArray().getValues().toByteArray();
			return calculate(mv, numberOfChunks, Bytes.asList(bytes), measuredValues.getFlagsList());
		case BYTE_STREAM_ARRAY:
			return createEmpty(mv.clearByteStreamArray());
		case DATE_ARRAY:
			List<Timestamp> timestamps = measuredValues.getDateArray().getValuesList();
			return calculateDate(mv, numberOfChunks, timestamps, measuredValues.getFlagsList());
		case DOUBLE_ARRAY:
			return calculate(mv, numberOfChunks, measuredValues.getDoubleArray().getValuesList(),
					measuredValues.getFlagsList());
		case DOUBLE_COMPLEX_ARRAY:
			return createEmpty(mv.clearDoubleComplexArray());
		case FLOAT_ARRAY:
			return calculate(mv, numberOfChunks, measuredValues.getFloatArray().getValuesList(),
					measuredValues.getFlagsList());
		case FLOAT_COMPLEX_ARRAY:
			return createEmpty(mv.clearFloatComplexArray());
		case INTEGER_ARRAY:
			return calculate(mv, numberOfChunks, measuredValues.getIntegerArray().getValuesList(),
					measuredValues.getFlagsList());
		case LONG_ARRAY:
			return calculate(mv, numberOfChunks, measuredValues.getLongArray().getValuesList(),
					measuredValues.getFlagsList());
		case SHORT_ARRAY:
			return calculate(mv, numberOfChunks, measuredValues.getShortArray().getValuesList(),
					measuredValues.getFlagsList());
		case STRING_ARRAY:
			return createEmpty(mv.clearStringArray());
		case VALUES_NOT_SET:
			throw new PreviewException(
					"Property 'values' of MeasuredValues with name '" + measuredValues.getName() + "' not set.");
		default:
			throw new PreviewException(
					"The value '" + mv.getValuesCase().name() + "' for Property 'values' of MeasuredValues with name '"
							+ measuredValues.getName() + "' is not supported.");
		}
	}

	/**
	 * Returns an empty builder.
	 * 
	 * @param mv
	 * @return a builder with no values or flags set
	 */
	private Mdm.PreviewValuesList.Builder createEmpty(Builder mv) {
		return Mdm.PreviewValuesList.newBuilder().addMin(mv.clearFlags().clearLength())
				.addMax(mv.clearFlags().clearLength()).addAvg(mv.clearFlags().clearLength());
	}

	/**
	 * Calculates min, max and avg for the given values for all data types except
	 * DT_DATE (@see this{@link #calculateDate(Builder, int, List, List)})
	 * 
	 * @param builder                 a builder to apply the values to.
	 * @param requestedNumberOfChunks number of chunks to calculate
	 * @param values                  measurement values
	 * @param flags                   list with flags
	 * @return an builder with the calculated values.
	 */
	private Mdm.PreviewValuesList.Builder calculate(Mdm.MeasuredValues.Builder builder, int requestedNumberOfChunks,
			List<? extends Number> values, List<Boolean> flags) {

		if (requestedNumberOfChunks < 1) {
			throw new PreviewException("Number of chunks requested must be positive!");
		}

		// numberOfChunks cannot be larger than length of data
		int numberOfChunks = Math.min(requestedNumberOfChunks, values.size());

		double chunkSize = values.size() / (double) numberOfChunks;

		DoubleArray.Builder minValues = DoubleArray.newBuilder();
		DoubleArray.Builder avgValues = DoubleArray.newBuilder();
		DoubleArray.Builder maxValues = DoubleArray.newBuilder();

		for (int chunkIndex = 0; chunkIndex < numberOfChunks; chunkIndex++) {
			double min = Double.MAX_VALUE;
			double sum = 0;
			double max = Double.MIN_VALUE;
			int count = 0;

			int startIndex = Ints.checkedCast(Math.round(chunkIndex * chunkSize));
			int endIndex = Ints.checkedCast(Math.round((chunkIndex + 1) * chunkSize));

			for (int valueIndex = startIndex; valueIndex < endIndex; valueIndex++) {
				if (valueIndex >= flags.size() || flags.get(valueIndex)) {
					double value = values.get(valueIndex).doubleValue();
					sum += value;
					min = Math.min(min, value);
					max = Math.max(max, value);
					count++;
				}
			}

			minValues.addValues(min);
			avgValues.addValues(sum / count);
			maxValues.addValues(max);
		}

		builder = builder.setLength(numberOfChunks);
		return PreviewValuesList.newBuilder().addMin(builder.setDoubleArray(minValues))
				.addAvg(builder.setDoubleArray(avgValues)).addMax(builder.setDoubleArray(maxValues));
	}

	/**
	 * Calculates min, max and avg for the given values for all data type DT_DATE.
	 * 
	 * @param builder                 a builder to apply the values to.
	 * @param requestedNumberOfChunks number of chunks to calculate
	 * @param values                  measurement values
	 * @param flags                   list with flags
	 * @return an builder with the calculated values.
	 */
	private Mdm.PreviewValuesList.Builder calculateDate(Mdm.MeasuredValues.Builder builder, int numberOfChunks,
			List<Timestamp> timestamps, List<Boolean> flags) {

		if (numberOfChunks < 1) {
			throw new PreviewException("Number of chunks requested must be positive!");
		}

		// numberOfChunks cannot be larger than length of data
		numberOfChunks = Math.min(numberOfChunks, timestamps.size());

		double chunkSize = timestamps.size() / (double) numberOfChunks;

		DateArray.Builder minValues = DateArray.newBuilder();
		DateArray.Builder avgValues = DateArray.newBuilder();
		DateArray.Builder maxValues = DateArray.newBuilder();

		for (int chunkIndex = 0; chunkIndex < numberOfChunks; chunkIndex++) {

			double sumSeconds = 0.0;
			double sumNanos = 0.0;

			Timestamp max = Timestamp.newBuilder().setSeconds(0L).setNanos(0).build();
			Timestamp min = Timestamp.newBuilder().setSeconds(Long.MAX_VALUE).setNanos(Integer.MAX_VALUE).build();
			int count = 0;

			int startIndex = Ints.checkedCast(Math.round(chunkIndex * chunkSize));
			int endIndex = Ints.checkedCast(Math.round((chunkIndex + 1) * chunkSize));

			for (int valueIndex = startIndex; valueIndex < endIndex; valueIndex++) {
				if (valueIndex >= flags.size() || flags.get(valueIndex)) {
					Timestamp value = timestamps.get(valueIndex);
					sumSeconds += value.getSeconds();
					sumNanos += value.getNanos();
					min = min(min, value);
					max = max(max, value);
					count++;
				}
			}
			minValues.addValues(min);
			maxValues.addValues(max);

			BigDecimal c = BigDecimal.valueOf(count);
			// calculate average and remainder
			BigDecimal[] avg = BigDecimal.valueOf(sumSeconds).add(BigDecimal.valueOf(sumNanos * 1E-9))
					.divideAndRemainder(c);

			// the remainder will be converted to nanoseconds
			avgValues.addValues(Timestamp.newBuilder().setSeconds(avg[0].longValue())
					.setNanos(avg[1].multiply(BigDecimal.valueOf(1E9)).divide(c, RoundingMode.HALF_UP).intValue()));
		}

		return PreviewValuesList.newBuilder().addMin(builder.setDateArray(minValues))
				.addAvg(builder.setDateArray(avgValues)).addMax(builder.setDateArray(maxValues));
	}

	/**
	 * Returns the smaller of the given timestamps.
	 * 
	 * @param t1 first timestamp
	 * @param t2 second timestamp
	 * @return t1, if t1 before t2 else t2
	 */
	private Timestamp min(Timestamp t1, Timestamp t2) {
		if (t1.getSeconds() < t2.getSeconds()) {
			return t1;
		} else if (t1.getSeconds() > t2.getSeconds()) {
			return t2;
		} else {
			return t1.getNanos() <= t2.getNanos() ? t1 : t2;
		}
	}

	/**
	 * Returns the larger of the given timestamps.
	 * 
	 * @param t1 first timestamp
	 * @param t2 second timestamp
	 * @return t1, if t1 after t2 else t2
	 */
	private Timestamp max(Timestamp t1, Timestamp t2) {
		if (t1.getSeconds() > t2.getSeconds()) {
			return t1;
		} else if (t1.getSeconds() < t2.getSeconds()) {
			return t2;
		} else {
			return t1.getNanos() >= t2.getNanos() ? t1 : t2;
		}
	}
}
