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

import java.time.LocalDateTime;
import java.util.Arrays;

import org.apache.commons.lang3.ArrayUtils;
import org.eclipse.mdm.api.base.model.AxisType;
import org.eclipse.mdm.api.base.model.DoubleComplex;
import org.eclipse.mdm.api.base.model.FileLink;
import org.eclipse.mdm.api.base.model.FloatComplex;
import org.eclipse.mdm.api.base.model.MeasuredValues;
import org.eclipse.mdm.api.base.model.MeasuredValues.ValueIterator;
import org.eclipse.mdm.api.base.model.ScalarType;
import org.eclipse.mdm.api.base.model.SequenceRepresentation;

/**
 * Helper class for measured values operations
 * 
 * @author Alexander Knoblauch
 *
 */
public class MeasuredValuesHelper {

	/**
	 * Map measurement values to given unit
	 * 
	 * @param measuredValues
	 * @param unitNew
	 * @return
	 */
	public static MeasuredValues mapUnitOfMeasuredValues(MeasuredValues measuredValues, String unitNew) {

		ScalarType scalarType = measuredValues.getScalarType();

		MeasuredValuesDTO values = null;

		if (scalarType.isString()) {
			values = getStringValues(measuredValues);
		} else if (scalarType.isDate()) {
			values = getDateValues(measuredValues);
		} else if (scalarType.isBoolean()) {
			values = getBooleanValues(measuredValues);
		} else if (scalarType.isByte()) {
			values = getByteValues(measuredValues);
		} else if (scalarType.isShort()) {
			values = getShortValues(measuredValues);
		} else if (scalarType.isInteger()) {
			values = getIntegerValues(measuredValues);
		} else if (scalarType.isLong()) {
			values = getLongValues(measuredValues);
		} else if (scalarType.isFloat()) {
			values = getFloatValues(measuredValues);
		} else if (scalarType.isDouble()) {
			values = getDoubleValues(measuredValues);
		} else if (scalarType.isByteStream()) {
			values = getByteStreamValues(measuredValues);
		} else if (scalarType.isFloatComplex()) {
			values = getFloatComplexValues(measuredValues);
		} else if (scalarType.isDoubleComplex()) {
			values = getDoubleComplexValues(measuredValues);
		} else if (scalarType.isFileLink()) {
			values = getFileLinkValues(measuredValues);
		} else if (scalarType.isBlob()) {
			values = getBlobValues(measuredValues);
		} else {
			throw new IllegalStateException(
					String.format("Unsupported ScalarType %s in MeasuredValues!", scalarType.name()));
		}

		return scalarType.createMeasuredValues(measuredValues.getName(), unitNew,
				measuredValues.getSequenceRepresentation(), measuredValues.getGenerationParameters(),
				measuredValues.isIndependent(), measuredValues.getAxisType(), values.getValues(), values.getFlags());

	}

	/**
	 * appending two measured values
	 * 
	 * @param measuredValues1
	 * @param measuredValues2
	 * @return appended measured values
	 * @throws ApiCopyException if the {@link ScalarType}s or units are different
	 */
	public static MeasuredValues appenMeasuredValues(MeasuredValues measuredValues1, MeasuredValues measuredValues2) {
		ScalarType scalarType = measuredValues1.getScalarType();

		if (!scalarType.equals(measuredValues2.getScalarType())) {
			throw new ApiCopyException("Error at appending measured values, ScalarType is different!");
		}

		if (!measuredValues1.getUnit().equals(measuredValues2.getUnit())) {
			throw new ApiCopyException("Error at appending measured values, Unit is different!");
		}

		Object valuesNew = null;
		boolean[] flagsNew = new boolean[0];

		if (scalarType.isString()) {
			MeasuredValuesDTO values1 = getStringValues(measuredValues1);
			MeasuredValuesDTO values2 = getStringValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((String[]) values1.getValues(), (String[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isDate()) {
			MeasuredValuesDTO values1 = getDateValues(measuredValues1);
			MeasuredValuesDTO values2 = getDateValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((LocalDateTime[]) values1.getValues(), (LocalDateTime[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isBoolean()) {
			MeasuredValuesDTO values1 = getBooleanValues(measuredValues1);
			MeasuredValuesDTO values2 = getBooleanValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((boolean[]) values1.getValues(), (boolean[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isByte()) {
			MeasuredValuesDTO values1 = getByteValues(measuredValues1);
			MeasuredValuesDTO values2 = getByteValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((byte[]) values1.getValues(), (byte[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isShort()) {
			MeasuredValuesDTO values1 = getShortValues(measuredValues1);
			MeasuredValuesDTO values2 = getShortValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((short[]) values1.getValues(), (short[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isInteger()) {
			MeasuredValuesDTO values1 = getIntegerValues(measuredValues1);
			MeasuredValuesDTO values2 = getIntegerValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((int[]) values1.getValues(), (int[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isLong()) {
			MeasuredValuesDTO values1 = getLongValues(measuredValues1);
			MeasuredValuesDTO values2 = getLongValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((long[]) values1.getValues(), (long[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isFloat()) {
			MeasuredValuesDTO values1 = getFloatValues(measuredValues1);
			MeasuredValuesDTO values2 = getFloatValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((float[]) values1.getValues(), (float[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isDouble()) {
			MeasuredValuesDTO values1 = getDoubleValues(measuredValues1);
			MeasuredValuesDTO values2 = getDoubleValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((double[]) values1.getValues(), (double[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isByteStream()) {
			MeasuredValuesDTO values1 = getByteStreamValues(measuredValues1);
			MeasuredValuesDTO values2 = getByteStreamValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((byte[][]) values1.getValues(), (byte[][]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isFloatComplex()) {
			MeasuredValuesDTO values1 = getFloatComplexValues(measuredValues1);
			MeasuredValuesDTO values2 = getFloatComplexValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((FloatComplex[]) values1.getValues(), (FloatComplex[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isDoubleComplex()) {
			MeasuredValuesDTO values1 = getDoubleComplexValues(measuredValues1);
			MeasuredValuesDTO values2 = getDoubleComplexValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((DoubleComplex[]) values1.getValues(), (DoubleComplex[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else if (scalarType.isFileLink()) {
			MeasuredValuesDTO values1 = getFileLinkValues(measuredValues1);
			MeasuredValuesDTO values2 = getFileLinkValues(measuredValues2);

			valuesNew = ArrayUtils.addAll((FileLink[]) values1.getValues(), (FileLink[]) values2.getValues());
			flagsNew = ArrayUtils.addAll(values1.getFlags(), values2.getFlags());
		} else {
			throw new IllegalStateException(
					String.format("Unsupported ScalarType %s in MeasuredValues!", scalarType.name()));
		}

		return scalarType.createMeasuredValues(measuredValues1.getName(), measuredValues1.getUnit(),
				measuredValues1.getSequenceRepresentation(), measuredValues1.getGenerationParameters(),
				measuredValues1.isIndependent(), measuredValues1.getAxisType(), valuesNew, flagsNew);
	}

	/**
	 * Creating MeasueredValues with only invalid values
	 * 
	 * @param name                   of the column
	 * @param scalarType             the {@link ScalarType}
	 * @param unit                   of the values
	 * @param sequenceRepresentation the {@link SequenceRepresentation}
	 * @param generationParameters
	 * @param independent
	 * @param axisType               the {@link AxisType}
	 * @param numberOfValues         the number of the measured values
	 * @return {@link MeasuredValues} object, which includes only invalid values
	 */
	public static MeasuredValues createEmptyValues(String name, ScalarType scalarType, String unit,
			SequenceRepresentation sequenceRepresentation, double[] generationParameters, boolean independent,
			AxisType axisType, int numberOfValues) {
		boolean[] flags = new boolean[numberOfValues];
		Arrays.fill(flags, false);

		Object values = null;

		if (scalarType.isString()) {
			values = new String[numberOfValues];
		} else if (scalarType.isDate()) {
			values = new LocalDateTime[numberOfValues];
		} else if (scalarType.isBoolean()) {
			values = new boolean[numberOfValues];
		} else if (scalarType.isByte()) {
			values = new byte[numberOfValues];
		} else if (scalarType.isShort()) {
			values = new short[numberOfValues];
		} else if (scalarType.isInteger()) {
			values = new int[numberOfValues];
		} else if (scalarType.isLong()) {
			values = new long[numberOfValues];
		} else if (scalarType.isFloat()) {
			values = new float[numberOfValues];
		} else if (scalarType.isDouble()) {
			values = new double[numberOfValues];
		} else if (scalarType.isByteStream()) {
			values = new byte[numberOfValues][];
		} else if (scalarType.isFloatComplex()) {
			values = new FloatComplex[numberOfValues];
		} else if (scalarType.isDoubleComplex()) {
			values = new DoubleComplex[numberOfValues];
		} else if (scalarType.isFileLink()) {
			values = new FileLink[numberOfValues];
		} else {
			throw new IllegalStateException(
					String.format("Unsupported ScalarType %s in MeasuredValues!", scalarType.name()));
		}

		return scalarType.createMeasuredValues(name, unit, sequenceRepresentation, generationParameters, independent,
				axisType, values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType
	 *         {@link String}
	 */
	private static MeasuredValuesDTO getStringValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		String[] values = new String[length];
		boolean[] flags = new boolean[length];

		ValueIterator<String> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}
		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType
	 *         {@link LocalDateTime}
	 */
	private static MeasuredValuesDTO getDateValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		LocalDateTime[] values = new LocalDateTime[length];
		boolean[] flags = new boolean[length];
		ValueIterator<LocalDateTime> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}
		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType boolean
	 */
	private static MeasuredValuesDTO getBooleanValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		boolean[] values = new boolean[length];
		boolean[] flags = new boolean[length];
		ValueIterator<Boolean> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}
		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType byte
	 */
	private static MeasuredValuesDTO getByteValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		byte[] values = new byte[length];
		boolean[] flags = new boolean[length];
		ValueIterator<Byte> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}
		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType short
	 */
	private static MeasuredValuesDTO getShortValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		short[] values = new short[length];
		boolean[] flags = new boolean[length];
		ValueIterator<Short> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}
		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType long
	 */
	private static MeasuredValuesDTO getLongValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		long[] values = new long[length];
		boolean[] flags = new boolean[length];
		ValueIterator<Long> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}
		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType float
	 */
	private static MeasuredValuesDTO getFloatValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		float[] values = new float[length];
		boolean[] flags = new boolean[length];
		ValueIterator<Float> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}
		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType int
	 */
	private static MeasuredValuesDTO getIntegerValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		int[] values = new int[length];
		boolean[] flags = new boolean[length];
		ValueIterator<Integer> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}
		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType double
	 */
	private static MeasuredValuesDTO getDoubleValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		double[] values = new double[length];
		boolean[] flags = new boolean[length];
		ValueIterator<Double> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}
		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType byte[]
	 */
	private static MeasuredValuesDTO getByteStreamValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		byte[][] values = new byte[length][];
		boolean[] flags = new boolean[length];
		ValueIterator<byte[]> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}

		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType
	 *         {@link FloatComplex}
	 */
	private static MeasuredValuesDTO getFloatComplexValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		boolean[] flags = new boolean[length];
		FloatComplex[] values = new FloatComplex[length];

		ValueIterator<FloatComplex> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}

		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType
	 *         {@link DoubleComplex}
	 */
	private static MeasuredValuesDTO getDoubleComplexValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		boolean[] flags = new boolean[length];
		DoubleComplex[] values = new DoubleComplex[length];

		ValueIterator<DoubleComplex> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}

		return new MeasuredValuesDTO(values, flags);
	}

	/**
	 * 
	 * @param measuredValues
	 * @return {@link MeasuredValuesDTO} values is an array of DataType
	 *         {@link FileLink}
	 */
	private static MeasuredValuesDTO getFileLinkValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		boolean[] flags = new boolean[length];
		FileLink[] values = new FileLink[length];

		ValueIterator<FileLink> iter = measuredValues.iterator();
		int count = 0;
		while (iter.hasNext()) {
			flags[count] = iter.isValid();
			values[count++] = iter.next();
		}

		return new MeasuredValuesDTO(values, flags);
	}

	private static MeasuredValuesDTO getBlobValues(MeasuredValues measuredValues) {
		int length = measuredValues.getLength();
		boolean[] flags = new boolean[length];
		ValueIterator<Object> iter = measuredValues.iterator();
		Object values = null;
		while (iter.hasNext()) {
			values = iter.next();
		}

		return new MeasuredValuesDTO(values, flags);
	}

}
