/********************************************************************************
 * 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.boundary;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.inject.Inject;

import org.eclipse.mdm.api.base.Transaction;
import org.eclipse.mdm.api.base.massdata.AnyTypeValuesBuilder;
import org.eclipse.mdm.api.base.massdata.ComplexNumericalValuesBuilder;
import org.eclipse.mdm.api.base.massdata.IndependentBuilder;
import org.eclipse.mdm.api.base.massdata.ReadRequest;
import org.eclipse.mdm.api.base.massdata.WriteRequest;
import org.eclipse.mdm.api.base.massdata.WriteRequestBuilder;
import org.eclipse.mdm.api.base.massdata.WriteRequestFinalizer;
import org.eclipse.mdm.api.base.model.AxisType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.DoubleComplex;
import org.eclipse.mdm.api.base.model.Environment;
import org.eclipse.mdm.api.base.model.FloatComplex;
import org.eclipse.mdm.api.base.model.MeasuredValues;
import org.eclipse.mdm.api.dflt.ApplicationContext;
import org.eclipse.mdm.api.dflt.EntityManager;
import org.eclipse.mdm.businessobjects.utils.PreviewHelper;
import org.eclipse.mdm.businessobjects.utils.ProtobufConverter;
import org.eclipse.mdm.connector.boundary.ConnectorService;
import org.eclipse.mdm.protobuf.Mdm;
import org.eclipse.mdm.protobuf.Mdm.MeasuredValuesList;
import org.eclipse.mdm.protobuf.Mdm.PreviewRequest;
import org.eclipse.mdm.protobuf.Mdm.PreviewValuesList;
import org.eclipse.mdm.protobuf.Mdm.WriteRequestList.WriteRequest.ExplicitData;
import org.eclipse.mdm.protobuf.Mdm.WriteRequestList.WriteRequest.ImplicitConstant;
import org.eclipse.mdm.protobuf.Mdm.WriteRequestList.WriteRequest.ImplicitLinear;
import org.eclipse.mdm.protobuf.Mdm.WriteRequestList.WriteRequest.ImplicitSaw;
import org.eclipse.mdm.protobuf.Mdm.WriteRequestList.WriteRequest.RawLinear;
import org.eclipse.mdm.protobuf.Mdm.WriteRequestList.WriteRequest.RawLinearCalibrated;
import org.eclipse.mdm.protobuf.Mdm.WriteRequestList.WriteRequest.RawPolynomial;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.primitives.Booleans;
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.common.primitives.Shorts;

@Stateless
public class ValuesService {

	private static final Logger LOG = LoggerFactory.getLogger(ValuesService.class);

	@Inject
	private ConnectorService connectorService;

	/**
	 * Loads multiple MeasuredValues as specified in ReadRequest.
	 * 
	 * @param sourceName       name of the source (MDM {@link Environment} name)
	 * @param protoReadRequest Protobuf ReadRequest
	 * @return the loaded MeasuredValuesList
	 */
	public MeasuredValuesList load(String sourceName, Mdm.ReadRequest protoReadRequest) {

		ApplicationContext context = connectorService.getContextByName(sourceName);

		ReadRequest readRequest = ProtobufConverter.convert(context, protoReadRequest);

		List<MeasuredValues> measuredValues = context.getEntityManager().get().readMeasuredValues(readRequest);

		return ProtobufConverter.convert(measuredValues);
	}

	/**
	 * Loads preview values for multiple channels as specified in
	 * {@link PreviewRequest}. The preview consists of minimum (min), maximum (max)
	 * and average (avg) values for each chunk of values. The number of chunks must
	 * be given in {@link PreviewRequest}.
	 * 
	 * @param sourceName       name of the source (MDM {@link Environment} name)
	 * @param protoReadRequest Protobuf {@link PreviewRequest}
	 * @return the loaded PreviewValuesList
	 */
	public PreviewValuesList preview(String sourceName, Mdm.PreviewRequest previewRequest) {
		ApplicationContext context = connectorService.getContextByName(sourceName);

		ReadRequest readRequest = ProtobufConverter.convert(context, previewRequest.getReadRequest());

		List<Mdm.MeasuredValues> measuredValues = ProtobufConverter
				.convert(context.getEntityManager().get().readMeasuredValues(readRequest)).getValuesList();

		// Calculate Preview
		return new PreviewHelper().calculatePreview(measuredValues, previewRequest.getNumberOfChunks());
	}

	/**
	 * Writes values for multiple Channels.
	 * 
	 * @param sourceName            name of the source (MDM {@link Environment}
	 *                              name)
	 * @param protoWriteRequestList Protobuf {@link WriteRequest}
	 */
	public void write(String sourceName, Mdm.WriteRequestList protoWriteRequestList) {
		ApplicationContext context = connectorService.getContextByName(sourceName);
		Supplier<ZoneId> zoneId = Suppliers
				.memoize(() -> getServerZoneId(context.getEntityManager().get().loadEnvironment()));

		List<WriteRequest> writeRequests = new ArrayList<>();
		for (Mdm.WriteRequestList.WriteRequest r : protoWriteRequestList.getValuesList()) {
			writeRequests.add(convert(context, r, zoneId));
		}

		Transaction t = context.getEntityManager().get().startTransaction();
		t.writeMeasuredValues(writeRequests);
		t.commit();
	}

	/**
	 * Converts a Protobuf to a api.base WritRequest.
	 * 
	 * @param context           {@link ApplicationContext} to write to.
	 * @param protoWriteRequest Data to write.
	 * @param zoneId            A supplier for a {@link ZoneId} which will be used,
	 *                          if Data with DT_DATE is written.
	 * @return converted {@link WriteRequest}
	 */
	private WriteRequest convert(ApplicationContext context, Mdm.WriteRequestList.WriteRequest protoWriteRequest,
			Supplier<ZoneId> zoneId) {
		EntityManager em = context.getEntityManager().get();

		ChannelGroup channelGroup = em.load(ChannelGroup.class, protoWriteRequest.getChannelGroupId());
		Channel channel = em.load(Channel.class, protoWriteRequest.getChannelId());
		AxisType axisType = ProtobufConverter.convert(protoWriteRequest.getAxisType());

		WriteRequestBuilder rb = WriteRequest.create(channelGroup, channel, axisType);

		WriteRequestFinalizer wrf;
		switch (protoWriteRequest.getDataCase()) {
		case EXPLICIT:
			wrf = setValues(rb.explicit(), protoWriteRequest.getExplicit(), zoneId);
			break;
		case IMPLICIT_CONSTANT:
			ImplicitConstant ic = protoWriteRequest.getImplicitConstant();
			wrf = rb.implicitConstant(ProtobufConverter.convert(ic.getScalarType()), ic.getOffset());
			break;
		case IMPLICIT_LINEAR:
			ImplicitLinear il = protoWriteRequest.getImplicitLinear();
			wrf = rb.implicitLinear(ProtobufConverter.convert(il.getScalarType()), il.getStart(), il.getIncrement());
			break;
		case IMPLICIT_SAW:
			ImplicitSaw is = protoWriteRequest.getImplicitSaw();
			wrf = rb.implicitSaw(ProtobufConverter.convert(is.getScalarType()), is.getStart(), is.getIncrement(),
					is.getStop());
			break;
		case RAW_LINEAR:
			RawLinear rl = protoWriteRequest.getRawLinear();
			wrf = setValues(rb.rawLinear(rl.getOffset(), rl.getFactor()), rl.getValues(), zoneId);
			break;
		case RAW_LINEAR_CALIBRATED:
			RawLinearCalibrated rlc = protoWriteRequest.getRawLinearCalibrated();
			wrf = setValues(rb.rawLinearCalibrated(rlc.getOffset(), rlc.getFactor(), rlc.getCalibration()),
					rlc.getValues(), zoneId);
			break;
		case RAW_POLYNOMIAL:
			RawPolynomial rp = protoWriteRequest.getRawPolynomial();
			wrf = setValues(rb.rawPolynomial(Doubles.toArray(rp.getCoefficientsList())), rp.getValues(), zoneId);
			break;
		case DATA_NOT_SET:
		default:
			throw new RuntimeException("Not supported yet: " + protoWriteRequest.getDataCase());

		}

		// TODO mkoller 04.11.2019, Unit conversion is not yet supported.

//		if (wrf instanceof UnitBuilder) {
//			// Unit convertion not supported yet!
//			Unit unit = context.getEntityManager().get().load(Unit.class, "" + protoWriteRequest.getUnitId());
//			wrf = ((UnitBuilder) wrf).sourceUnit(unit);
//		}
//		if (wrf instanceof UnitIndependentBuilder) {
//			// Unit convertion not supported yet!
//			Unit unit = context.getEntityManager().get().load(Unit.class, "" + protoWriteRequest.getUnitId());
//			wrf = ((UnitBuilder) wrf).sourceUnit(unit);
//		}

		if (wrf instanceof IndependentBuilder) {
			wrf = ((IndependentBuilder) wrf).independent(protoWriteRequest.getIndependent());
		}
		return wrf.build();

	}

	/**
	 * Helper function to set values for the appropriate datatype in an
	 * {@link AnyTypeValuesBuilder}
	 * 
	 * @param builder
	 * @param explicitData
	 * @param zoneId
	 * @return {@link WriteRequestFinalizer}
	 */
	private WriteRequestFinalizer setValues(AnyTypeValuesBuilder builder, ExplicitData explicitData,
			Supplier<ZoneId> zoneId) {
		boolean[] flags = Booleans.toArray(explicitData.getFlagsList());
		switch (explicitData.getValuesCase()) {
		case STRING_ARRAY:
			String[] strings = ProtobufConverter.convertStrings(explicitData.getStringArray());
			return (flags.length > 0) ? builder.stringValues(strings, flags) : builder.stringValues(strings);
		case DATE_ARRAY:
			LocalDateTime[] dates = ProtobufConverter.convertDates(explicitData.getDateArray(), zoneId.get());
			return (flags.length > 0) ? builder.dateValues(dates, flags) : builder.dateValues(dates);
		case BOOLEAN_ARRAY:
			boolean[] booleans = Booleans.toArray(explicitData.getBooleanArray().getValuesList());
			return (flags.length > 0) ? builder.booleanValues(booleans, flags) : builder.booleanValues(booleans);
		case BYTE_STREAM_ARRAY:
			byte[][] byteStreams = ProtobufConverter
					.convertByteStreams(explicitData.getByteStreamArray().getValuesList());
			return (flags.length > 0) ? builder.byteStreamValues(byteStreams, flags)
					: builder.byteStreamValues(byteStreams);
		case BYTE_ARRAY:
		case SHORT_ARRAY:
		case INTEGER_ARRAY:
		case LONG_ARRAY:
		case FLOAT_ARRAY:
		case DOUBLE_ARRAY:
		case FLOAT_COMPLEX_ARRAY:
		case DOUBLE_COMPLEX_ARRAY:
			return setValues((ComplexNumericalValuesBuilder) builder, explicitData, zoneId);
		case VALUES_NOT_SET:
		default:
			throw new RuntimeException("No explicit data set!");
		}
	}

	/**
	 * Helper function to set values for the appropriate datatype in a
	 * {@link ComplexNumericalValuesBuilder}.
	 * 
	 * @param builder
	 * @param explicitData
	 * @param zoneId
	 * @return {@link WriteRequestFinalizer}
	 */
	private WriteRequestFinalizer setValues(ComplexNumericalValuesBuilder builder, ExplicitData explicitData,
			Supplier<ZoneId> zoneId) {
		boolean[] flags = Booleans.toArray(explicitData.getFlagsList());
		switch (explicitData.getValuesCase()) {
		case STRING_ARRAY:
		case DATE_ARRAY:
		case BOOLEAN_ARRAY:
		case BYTE_STREAM_ARRAY:
			throw new RuntimeException(
					explicitData.getValuesCase() + " not supported by ComplexNumericalValuesBuilder!");
		case BYTE_ARRAY:
			byte[] bytes = explicitData.getByteArray().getValues().toByteArray();
			return (flags.length > 0) ? builder.byteValues(bytes, flags) : builder.byteValues(bytes);
		case SHORT_ARRAY:
			short[] shorts = Shorts.toArray(explicitData.getShortArray().getValuesList());
			return (flags.length > 0) ? builder.shortValues(shorts, flags) : builder.shortValues(shorts);
		case INTEGER_ARRAY:
			int[] ints = Ints.toArray(explicitData.getIntegerArray().getValuesList());
			return (flags.length > 0) ? builder.integerValues(ints, flags) : builder.integerValues(ints);
		case LONG_ARRAY:
			long[] longs = Longs.toArray(explicitData.getLongArray().getValuesList());
			return (flags.length > 0) ? builder.longValues(longs, flags) : builder.longValues(longs);
		case FLOAT_ARRAY:
			float[] floats = Floats.toArray(explicitData.getFloatArray().getValuesList());
			return (flags.length > 0) ? builder.floatValues(floats, flags) : builder.floatValues(floats);
		case DOUBLE_ARRAY:
			double[] doubles = Doubles.toArray(explicitData.getDoubleArray().getValuesList());
			return (flags.length > 0) ? builder.doubleValues(doubles, flags) : builder.doubleValues(doubles);
		case FLOAT_COMPLEX_ARRAY:
			FloatComplex[] floatComplexes = ProtobufConverter
					.convertFloatComplex(explicitData.getFloatComplexArray().getValuesList());
			return (flags.length > 0) ? builder.floatComplexValues(floatComplexes, flags)
					: builder.floatComplexValues(floatComplexes);
		case DOUBLE_COMPLEX_ARRAY:
			DoubleComplex[] doubleComplexes = ProtobufConverter
					.convertDoubleComplex(explicitData.getDoubleComplexArray().getValuesList());
			return (flags.length > 0) ? builder.doubleComplexValues(doubleComplexes, flags)
					: builder.doubleComplexValues(doubleComplexes);
		case VALUES_NOT_SET:
		default:
			throw new RuntimeException("No explicit data set!");
		}
	}

	/**
	 * Returns the ZonId configured in the {@link Environment}
	 * 
	 * @param env {@link Environment} for extracting the ZoneId
	 * @return ZonId configured in the {@link Environment}
	 */
	private ZoneId getServerZoneId(Environment env) {
		String timezone = env.getTimezone();
		try {
			return ZoneId.of(timezone);
		} catch (Exception e) {
			if (LOG.isDebugEnabled()) {
				LOG.debug("Timezone '" + timezone + "' of Environment '" + env.getName() + "' is invalid!", e);
			} else {
				LOG.warn("Timezone '" + timezone + "' of Environment '" + env.getName() + "' is invalid!");
			}
			return ZoneId.systemDefault();
		}
	}
}
