/********************************************************************************
 * 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.businessobjects.utils;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.List;

import org.assertj.core.util.DoubleComparator;
import org.eclipse.mdm.protobuf.Mdm.ByteArray;
import org.eclipse.mdm.protobuf.Mdm.DateArray;
import org.eclipse.mdm.protobuf.Mdm.DoubleArray;
import org.eclipse.mdm.protobuf.Mdm.FloatArray;
import org.eclipse.mdm.protobuf.Mdm.IntegerArray;
import org.eclipse.mdm.protobuf.Mdm.LongArray;
import org.eclipse.mdm.protobuf.Mdm.MeasuredValues;
import org.eclipse.mdm.protobuf.Mdm.PreviewValuesList;
import org.eclipse.mdm.protobuf.Mdm.ScalarType;
import org.eclipse.mdm.protobuf.Mdm.ShortArray;
import org.eclipse.mdm.protobuf.Mdm.StringArray;
import org.junit.Test;

import com.google.common.primitives.Doubles;
import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.protobuf.ByteString;
import com.google.protobuf.Timestamp;

public class PreviewHelperTest {

	private static final DoubleComparator COMP = new DoubleComparator(1.0E-6);

	private PreviewHelper helper = new PreviewHelper();

	private final List<String> stringValues = Arrays.asList("one", "two", "three", "four", "five", "six");
	private final MeasuredValues mv6Strings = MeasuredValues.newBuilder()
			.setStringArray(StringArray.newBuilder().addAllValues(stringValues)).setLength(stringValues.size()).build();

	private final ByteString byteValues = ByteString
			.copyFrom(new byte[] { (byte) 1, (byte) 2, (byte) 3, (byte) 1, (byte) 4, (byte) 2 });
	private final MeasuredValues mv6Bytes = MeasuredValues.newBuilder()
			.setByteArray(ByteArray.newBuilder().setValues(byteValues)).setLength(byteValues.size()).build();

	private final List<Integer> shortValues = Ints.asList(1, 2, 3, 1, 4, 2);
	private final MeasuredValues mv6Shorts = MeasuredValues.newBuilder()
			.setShortArray(ShortArray.newBuilder().addAllValues(shortValues)).setLength(shortValues.size()).build();

	private final List<Integer> intValues = Ints.asList(1, 2, 3, 1, 4, 2);
	private final MeasuredValues mv6Ints = MeasuredValues.newBuilder()
			.setIntegerArray(IntegerArray.newBuilder().addAllValues(intValues)).setLength(intValues.size()).build();

	private final List<Long> longValues = Longs.asList(1L, 2L, 3L, 1L, 4L, 2L);
	private final MeasuredValues mv6Longs = MeasuredValues.newBuilder()
			.setLongArray(LongArray.newBuilder().addAllValues(longValues)).setLength(longValues.size()).build();

	private final List<Float> floatValues = Floats.asList(1.0f, 2.0f, 3.0f, 1.1f, 4.4f, 2.2f);
	private final MeasuredValues mv6Floats = MeasuredValues.newBuilder()
			.setFloatArray(FloatArray.newBuilder().addAllValues(floatValues)).setLength(floatValues.size()).build();

	private final List<Double> doubleValues = Doubles.asList(1.0, 2.0, 3.0, 1.1, 4.4, 2.2);
	private final MeasuredValues mv6Doubles = MeasuredValues.newBuilder()
			.setDoubleArray(DoubleArray.newBuilder().addAllValues(doubleValues)).setLength(doubleValues.size()).build();

	@Test
	public void testInvalidNumberOfChunks() {

		assertThatThrownBy(() -> helper.calculatePreview(mv6Doubles, 0)).isInstanceOf(PreviewException.class)
				.hasMessage("Number of chunks requested must be positive!");

		assertThatThrownBy(() -> helper.calculatePreview(mv6Doubles, -1)).isInstanceOf(PreviewException.class)
				.hasMessage("Number of chunks requested must be positive!");
	}

	@Test
	public void testChunkSizeInteger() {
		PreviewValuesList pv = helper.calculatePreview(mv6Doubles, 2).build();
		assertThat(pv.getAvgCount()).isEqualTo(1);
		assertThat(pv.getAvg(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.0,
				2.56666666666);
	}

	@Test
	public void testChunkSizeFloat() {
		PreviewValuesList pv = helper.calculatePreview(mv6Doubles, 4).build();

		assertThat(pv.getMinCount()).isEqualTo(1);
		assertThat(pv.getMaxCount()).isEqualTo(1);
		assertThat(pv.getAvgCount()).isEqualTo(1);

		assertThat(pv.getMin(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0, 3.0,
				1.1, 2.2);
		assertThat(pv.getMax(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.0, 3.0,
				4.4, 2.2);
		assertThat(pv.getAvg(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.5, 3.0,
				2.75, 2.2);
	}

	@Test
	public void testChunkSizeFloat2() {
		PreviewValuesList pv = helper.calculatePreview(mv6Doubles, 5).build();

		assertThat(pv.getMinCount()).isEqualTo(1);
		assertThat(pv.getMaxCount()).isEqualTo(1);
		assertThat(pv.getAvgCount()).isEqualTo(1);

		assertThat(pv.getMin(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0, 2.0,
				1.1, 4.4, 2.2);
		assertThat(pv.getMax(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0, 2.0,
				3.0, 4.4, 2.2);
		assertThat(pv.getAvg(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0, 2.0,
				2.05, 4.4, 2.2);
	}

	@Test
	public void testNumberOfChunksEqualsNumberOfValues() {
		PreviewValuesList pv = helper.calculatePreview(mv6Doubles, 6).build();

		assertThat(pv.getMinCount()).isEqualTo(1);
		assertThat(pv.getMaxCount()).isEqualTo(1);
		assertThat(pv.getAvgCount()).isEqualTo(1);

		assertThat(pv.getMin(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).isEqualTo(doubleValues);
		assertThat(pv.getMax(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).isEqualTo(doubleValues);
		assertThat(pv.getAvg(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).isEqualTo(doubleValues);
	}

	@Test
	public void testNumberOfChunksLargerThanNumberOfValues() {
		PreviewValuesList pv = helper.calculatePreview(mv6Doubles, 7).build();

		assertThat(pv.getMinCount()).isEqualTo(1);
		assertThat(pv.getMaxCount()).isEqualTo(1);
		assertThat(pv.getAvgCount()).isEqualTo(1);

		assertThat(pv.getMin(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).isEqualTo(doubleValues);
		assertThat(pv.getMax(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).isEqualTo(doubleValues);
		assertThat(pv.getAvg(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).isEqualTo(doubleValues);
	}

	@Test
	public void testMultipleChannels() {
		PreviewValuesList pv = helper.calculatePreview(
				Arrays.asList(mv6Bytes, mv6Shorts, mv6Ints, mv6Longs, mv6Floats, mv6Doubles, mv6Strings), 2);

		assertThat(pv.getMinCount()).isEqualTo(7);
		assertThat(pv.getMaxCount()).isEqualTo(7);
		assertThat(pv.getAvgCount()).isEqualTo(7);

		assertThat(pv.getMin(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0,
				1.0);
		assertThat(pv.getMax(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(3.0,
				4.0);
		assertThat(pv.getAvg(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.0,
				2.33333333333);

		assertThat(pv.getMin(1).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0,
				1.0);
		assertThat(pv.getMax(1).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(3.0,
				4.0);
		assertThat(pv.getAvg(1).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.0,
				2.33333333333);

		assertThat(pv.getMin(2).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0,
				1.0);
		assertThat(pv.getMax(2).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(3.0,
				4.0);
		assertThat(pv.getAvg(2).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.0,
				2.33333333333);

		assertThat(pv.getMin(3).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0,
				1.0);
		assertThat(pv.getMax(3).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(3.0,
				4.0);
		assertThat(pv.getAvg(3).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.0,
				2.33333333333);

		assertThat(pv.getMin(4).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0,
				1.1);
		assertThat(pv.getMax(4).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(3.0,
				4.4);
		assertThat(pv.getAvg(4).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.0,
				2.56666666666);

		assertThat(pv.getMin(5).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(1.0,
				1.1);
		assertThat(pv.getMax(5).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(3.0,
				4.4);
		assertThat(pv.getAvg(5).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.0,
				2.56666666666);

		assertThat(pv.getMin(6)).isEqualTo(MeasuredValues.newBuilder().setScalarType(ScalarType.DOUBLE).build());
		assertThat(pv.getMax(6)).isEqualTo(MeasuredValues.newBuilder().setScalarType(ScalarType.DOUBLE).build());
		assertThat(pv.getAvg(6)).isEqualTo(MeasuredValues.newBuilder().setScalarType(ScalarType.DOUBLE).build());
	}

	@Test
	public void testFlags() {
		MeasuredValues mv6IntsWithFlags = mv6Ints.toBuilder()
				.addAllFlags(Arrays.asList(false, true, true, true, false, false)).build();

		// 1, 2, 3, 1, 4, 2
		PreviewValuesList pv = helper.calculatePreview(mv6IntsWithFlags, 2).build();
		assertThat(pv.getAvgCount()).isEqualTo(1);
		assertThat(pv.getAvg(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.5,
				1.0);
		assertThat(pv.getMin(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(2.0,
				1.0);
		assertThat(pv.getMax(0).getDoubleArray().getValuesList()).usingElementComparator(COMP).containsExactly(3.0,
				1.0);
	}

	@Test
	public void testTimestamps() {

		final List<Timestamp> dateValues = Arrays.asList(toTimestamp("2019-02-01T06:30:00.500"),
				toTimestamp("2019-02-02T06:30:00.500"), toTimestamp("2019-02-03T06:30:00.500"),
				toTimestamp("2019-04-01T06:10:00.100"), toTimestamp("2019-04-01T07:40:00.200"),
				toTimestamp("2019-04-01T09:10:00.300"));
		final MeasuredValues mv6Dates = MeasuredValues.newBuilder()
				.setDateArray(DateArray.newBuilder().addAllValues(dateValues)).setLength(dateValues.size()).build();

		PreviewValuesList pv = helper.calculatePreview(mv6Dates, 2).build();
		assertThat(pv.getAvgCount()).isEqualTo(1);
		assertThat(pv.getMin(0).getDateArray().getValuesList()).containsExactly(toTimestamp("2019-02-01T06:30:00.500"),
				toTimestamp("2019-04-01T06:10:00.100"));
		assertThat(pv.getMax(0).getDateArray().getValuesList()).containsExactly(toTimestamp("2019-02-03T06:30:00.500"),
				toTimestamp("2019-04-01T09:10:00.300"));
		assertThat(pv.getAvg(0).getDateArray().getValuesList()).containsExactly(toTimestamp("2019-02-02T06:30:00.500"),
				toTimestamp("2019-04-01T07:40:00.200"));
	}

	@Test
	public void testTimestampFlags() {
		final List<Timestamp> dateValues = Arrays.asList(toTimestamp("2019-02-01T06:30:00.500"),
				toTimestamp("2019-02-02T06:30:00.500"), toTimestamp("2019-02-03T06:30:00.500"),
				toTimestamp("2019-04-01T06:10:00.100"), toTimestamp("2019-04-01T07:40:00.200"),
				toTimestamp("2019-04-01T09:10:00.300"));
		final MeasuredValues mv6Dates = MeasuredValues.newBuilder()
				.setDateArray(DateArray.newBuilder().addAllValues(dateValues)).setLength(dateValues.size())
				.addAllFlags(Arrays.asList(false, true, true, true, false, false)).build();

		PreviewValuesList pv = helper.calculatePreview(mv6Dates, 2).build();
		assertThat(pv.getAvgCount()).isEqualTo(1);
		assertThat(pv.getMin(0).getDateArray().getValuesList()).containsExactly(toTimestamp("2019-02-02T06:30:00.500"),
				toTimestamp("2019-04-01T06:10:00.100"));
		assertThat(pv.getMax(0).getDateArray().getValuesList()).containsExactly(toTimestamp("2019-02-03T06:30:00.500"),
				toTimestamp("2019-04-01T06:10:00.100"));
		assertThat(pv.getAvg(0).getDateArray().getValuesList()).containsExactly(toTimestamp("2019-02-02T18:30:00.500"),
				toTimestamp("2019-04-01T06:10:00.100"));
	}

	private Timestamp toTimestamp(String datetime) {
		Instant instant = LocalDateTime.parse(datetime).toInstant(ZoneOffset.UTC);

		return Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build();
	}
}
