/********************************************************************************
 * Copyright (c) 2015-2020 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.base.model;

import static java.util.stream.IntStream.range;
import static org.eclipse.mdm.api.base.model.Value.readAt;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;

import org.eclipse.mdm.api.base.massdata.ExternalComponent;

/**
 * Class represents a sequence of measured values.
 *
 * @since 1.0.0
 * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
 * @author Sebastian Dirsch, Gigatronik Ingolstadt GmbH
 */
public final class MeasuredValues {

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

	private final ScalarType scalarType;
	private final Object values;
	private final boolean[] flags;

	/*
	 * TODO: - replace name and unit with the corresponding Channel & Unit entities
	 * - provide further information if required - provide an overall offset for
	 * this value sequence
	 */

	private final String name;
	private final String unit;

	private final int length;

	private final SequenceRepresentation sequenceRepresentation;
	private final double[] generationParameters;
	private final boolean independent;
	private final AxisType axisType;

	private final List<ExternalComponent> externalComponents;
	private final Short globalFlag;
	// ======================================================================
	// Constructors
	// ======================================================================

	/**
	 * Constructor.
	 *
	 * @param scalarType             The {@link ScalarType} of this measured values.
	 * @param name                   This is the name of the corresponding
	 *                               {@link Channel}.
	 * @param unit                   Name of the unit the contained values are of.
	 * @param sequenceRepresentation The {@link SequenceRepresentation} of the
	 *                               measured values.
	 * @param generationParameters   The generation parameters for the measured
	 *                               values.
	 * @param independent            The independent flag of the measured values.
	 * @param axisType               The {@link AxisType} of the measured values.
	 * @param values                 The measured values.
	 * @param flags                  The validity flags of the measured values.
	 * @throws IllegalArgumentException Thrown if values or flags is null or length
	 *                                  of values and flags is not equal.
	 */
	MeasuredValues(ScalarType scalarType, String name, String unit, SequenceRepresentation sequenceRepresentation,
			double[] generationParameters, boolean independent, AxisType axisType, Object values, boolean[] flags) {
		this.name = name;
		this.unit = (unit == null ? "" : unit);
		this.scalarType = scalarType;
		this.sequenceRepresentation = sequenceRepresentation.getNonExternalCounterpart();
		this.generationParameters = generationParameters;
		this.independent = independent;
		this.axisType = axisType;
		this.values = values;

		if (values == null || flags == null) {
			throw new IllegalArgumentException("Neither values nor flags is allowed to be null.");
		} else if (Array.getLength(values) != flags.length) {
			throw new IllegalArgumentException("Length of values and flags is not equal.");
		}

		this.flags = Arrays.copyOf(flags, flags.length);
		
		length = flags.length;
		this.externalComponents = null;
		this.globalFlag = null;
	}
	
	/**
	 * Constructor.
	 *
	 * @param scalarType             The {@link ScalarType} of this measured values.
	 * @param name                   This is the name of the corresponding
	 *                               {@link Channel}.
	 * @param unit                   Name of the unit the contained values are of.
	 * @param sequenceRepresentation The {@link SequenceRepresentation} of the
	 *                               measured values.
	 * @param generationParameters   The generation parameters for the measured
	 *                               values.
	 * @param independent            The independent flag of the measured values.
	 * @param axisType               The {@link AxisType} of the measured values.
	 * @param externalComponents     The list of the {@link ExternalComponent}s.
	 * @throws IllegalArgumentException Thrown if values or flags is null or length
	 *                                  of values and flags is not equal.
	 */
	MeasuredValues(ScalarType scalarType, String name, String unit, SequenceRepresentation sequenceRepresentation,
			double[] generationParameters, boolean independent, AxisType axisType, Short globalFlag, List<ExternalComponent> externalComponents) {
		this.name = name;
		this.unit = (unit == null ? "" : unit);
		this.scalarType = scalarType;
		this.sequenceRepresentation = sequenceRepresentation;
		this.generationParameters = generationParameters;
		this.independent = independent;
		this.axisType = axisType;
		this.values = null;
		this.flags = null;

		if (externalComponents == null) {
			throw new IllegalArgumentException("ExternalComponents is not allowed to be null.");
		} 
		
		this.length = -1;
		
		this.externalComponents = externalComponents;
		this.globalFlag = globalFlag;
	}

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

	/**
	 * Returns the name of this measured values sequence.
	 *
	 * @return The name is returned.
	 */
	public String getName() {
		return name;
	}

	/**
	 * Returns the unit name for this measured values sequence.
	 *
	 * @return The unit name is returned.
	 */
	public String getUnit() {
		return unit;
	}

	/**
	 * Returns the {@link ScalarType} of this measured values sequence.
	 *
	 * @return The {@code ScalarType} is returned.
	 */
	public ScalarType getScalarType() {
		return scalarType;
	}

	/**
	 * Returns the number of values of this measured values sequence.
	 *
	 * @return The number of values is returned.
	 */
	public int getLength() {
		return length;
	}

	/**
	 * Returns the {@link SequenceRepresentation} of this measured values sequence.
	 *
	 * @return The {@code SequenceRepresentation} is returned.
	 */
	public SequenceRepresentation getSequenceRepresentation() {
		return sequenceRepresentation;
	}

	/**
	 * Returns the generation parameters for this measured values sequence.
	 *
	 * @return The generation parameters are returned.
	 */
	public double[] getGenerationParameters() {
		return generationParameters;
	}

	/**
	 * Returns the independent flag of this measured values sequence.
	 *
	 * @return The independent flag is returned.
	 */
	public boolean isIndependent() {
		return independent;
	}

	/**
	 * Returns the {@link AxisType} of this measured values sequence.
	 *
	 * @return The {@code AxisType} is returned.
	 */
	public AxisType getAxisType() {
		return axisType;
	}

	/**
	 * Does this MeasuredValues have {@link ExternalComponent}s attached (instead of values)?
	 * 
	 * @return true if {@link ExternalComponent}s are present, false otherwise.
	 */
	public boolean hasExternalComponents() {
		return externalComponents != null;
	}

	/**
	 * Returns the list of {@link ExternalComponent}s attached to this MeasuredValues
	 * 
	 * @return An unmodifiable view of the list of {@link ExternalComponent}s or an empty list if there are none.
	 */
	public List<ExternalComponent> getExternalComponents() {
		if (hasExternalComponents()) {
			return Collections.unmodifiableList(externalComponents);
		} else {
			return Collections.emptyList();
		}
	}

	/**
	 * Returns a typed {@link ValueIterator}. Its usage is described below:
	 *
	 * <pre>
	 * // assume the measuredValues().getScalarType() == ScalarType.BYTE
	 * ValueIterator&lt;Byte&gt; valueIterator = measuredValues().iterator();
	 * while (valueIterator.hasNext()) {
	 * 	boolean isCurrentValid = valueIterator.isValid();
	 * 	Byte currentValue = valueIterator.next();
	 * }
	 * </pre>
	 *
	 * @param <E> This type has to be derived from the {@link ScalarType} of this
	 *            measured values.
	 * @return A typed {@code ValueIterator} is returned.
	 */
	public <E> ValueIterator<E> iterator() {
		// TODO provide custom implementations for each type and typed
		// nextType() methods
		// idea: getScalarType().createIterator(values, flags); // <- package
		// private
		return new ValueIterator<E>() {
			private int index = 0;

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

			@Override
			public boolean isValid() {
				return flags[index];
			}

			@Override
			@SuppressWarnings("unchecked")
			public E next() {
				if (hasNext()) {
					return (E) Array.get(values, index++);
				}
				throw new NoSuchElementException("Subsequent value is not available.");
			}
		};
	}

	/**
	 * Returns a human readable {@code String} representation of this measured
	 * values. If this sequence contains more than 10 values, only the first and
	 * last 5 values are written. If a value is marked as not valid, then 'XX' is
	 * written instead of its value.
	 *
	 * @return The {@code String} representation of this entity.
	 */
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("MeasuredValues(ChannelName = ").append(getName());
		sb.append(", ScalarType = ").append(getScalarType());

		if (!getUnit().isEmpty()) {
			sb.append(", Unit = ").append(getUnit());
		}

		sb.append(", Values = [");
		String notValidMarker = "XX";
		if (getLength() > 10) {
			sb.append(range(0, 5).mapToObj(i -> flags[i] ? readAt(values, i) : notValidMarker)
					.collect(Collectors.joining(", ")));
			sb.append(", ..., ");
			sb.append(range(length - 5, length).mapToObj(i -> flags[i] ? readAt(values, i) : notValidMarker)
					.collect(Collectors.joining(", ")));
		} else if (getLength() > 0) {
			sb.append(range(0, length).mapToObj(i -> flags[i] ? readAt(values, i) : notValidMarker)
					.collect(Collectors.joining(", ")));
		}

		return sb.append("])").toString();
	}

	// ======================================================================
	// Inner Types
	// ======================================================================

	/**
	 * The measured values iterator.
	 *
	 * @param <E> Type of the returned values.
	 * @since 1.0.0
	 * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
	 */
	public interface ValueIterator<E> extends Iterator<E> {

		/**
		 * Returns true if the current value is marked as valid.
		 *
		 * @return True if current value is valid.
		 */
		boolean isValid();

	}

}
