/*=============================================================================#
 # Copyright (c) 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.data.impl;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import static org.eclipse.statet.rj.data.impl.AbstractRStore.DEFAULT_LONG_DATA_SEGMENT_LENGTH;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Function;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.rj.data.RComplexStore;
import org.eclipse.statet.rj.data.RComplexStore.Complex;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RStore;


@NonNullByDefault
public abstract class RComplexStoreTest extends AbstractRStoreTest {
	
	
	static class CplxCaseData extends CaseData<RComplexStore> {
		
		final static Function<CplxCaseData, RComplexStore> REF_CONSTRUCTOR= new RComplexB32StoreTest()::createStore;
		
		final double[] realValues;
		final double[] imaginaryValues;
		
		
		public CplxCaseData(final String label, final double[] realValues, final double[] imaginaryValues,
				final boolean[] nas) {
			super(label, nas);
			assert (realValues.length == this.length);
			assert (imaginaryValues.length == this.length);
			this.realValues= realValues;
			this.imaginaryValues= imaginaryValues;
			
			setReference(REF_CONSTRUCTOR.apply(this));
		}
		
		public CplxCaseData(final String label, final double[] realValues, final double[] imaginaryValues) {
			super(label, realValues.length);
			assert (realValues.length == this.length);
			assert (imaginaryValues.length == this.length);
			this.realValues= realValues;
			this.imaginaryValues= imaginaryValues;
			
			setReference(REF_CONSTRUCTOR.apply(this));
		}
		
	}
	
	protected static final List<CplxCaseData> DEFAULT_DATA_SOURCES;
	static {
		final var datas= new ArrayList<CplxCaseData>();
		
		datas.add(new CplxCaseData("empty", new double[0], new double[0]));
		
		datas.add(new CplxCaseData("single-0", new double[] { 0 }, new double[] { 0 }));
		datas.add(new CplxCaseData("single-1", new double[] { 1 }, new double[] { 0 }));
		datas.add(new CplxCaseData("single-i1", new double[] { 0 }, new double[] { 1 }));
		datas.add(new CplxCaseData("single-NA", new double[] { 0 }, new double[] { 0 }, new boolean[] { true }));
		
		{	final double[] realValues= new double[0xFF];
			final double[] imaginaryValues= new double[realValues.length];
			final boolean[] nas= new boolean[realValues.length];
			int i= 0;
			realValues[i++]= 0;
			realValues[i++]= -0;
			realValues[i++]= +1;
			realValues[i++]= -1;
			realValues[i++]= Double.MIN_NORMAL;
			realValues[i++]= Double.MIN_VALUE;
			realValues[i++]= Double.MAX_VALUE;
			realValues[i++]= Double.POSITIVE_INFINITY;
			realValues[i++]= -Double.NEGATIVE_INFINITY;
			realValues[i++]= Double.NaN;
			imaginaryValues[i++]= -0;
			imaginaryValues[i++]= -1;
			imaginaryValues[i++]= +1;
			imaginaryValues[i++]= Double.MIN_NORMAL;
			imaginaryValues[i++]= Double.MIN_VALUE;
			imaginaryValues[i++]= -Double.MAX_VALUE;
			imaginaryValues[i++]= Double.POSITIVE_INFINITY;
			imaginaryValues[i++]= -Double.NEGATIVE_INFINITY;
			nas[i++]= true;
			
			datas.add(new CplxCaseData("special", realValues, imaginaryValues, nas));
		}
		
		{	final Random rand= new Random(16857);
			final double[] realValues= new double[100000];
			final double[] imaginaryValues= new double[realValues.length];
			for (int i= 0; i < realValues.length; i++) {
				realValues[i]= rand.nextDouble();
				imaginaryValues[i]= rand.nextDouble();
			}
			datas.add(new CplxCaseData("rand100000", realValues, imaginaryValues));
		}
		if (isBigDataEnabled(24)) {
			final Random rand= new Random(46);
			final double[] realValues= new double[DEFAULT_LONG_DATA_SEGMENT_LENGTH * 2 + 13];
			final double[] imaginaryValues= new double[DEFAULT_LONG_DATA_SEGMENT_LENGTH * 2 + 13];
			for (int i= 0; i < realValues.length; i++) {
				realValues[i]= rand.nextDouble();
			}
			datas.add(new CplxCaseData("randMultiSeg", realValues, imaginaryValues));
		}
		
		DEFAULT_DATA_SOURCES= datas;
	}
	
	
	public RComplexStoreTest() {
	}
	
	
	public static List<CplxCaseData> provideCaseDatas() {
		return new ArrayList<>(DEFAULT_DATA_SOURCES);
	}
	
	protected abstract RComplexStore createStore(final CplxCaseData data);
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getStoreType(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		assertEquals(RStore.COMPLEX, store.getStoreType());
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getBaseVectorRClassName(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		assertEquals(RObject.CLASSNAME_COMPLEX, store.getBaseVectorRClassName());
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void length(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		checkLength(data, store);
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void isNA(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		checkIsNA(data, store);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void isMissing(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]
					|| Double.isNaN(data.realValues[i0]) || Double.isNaN(data.imaginaryValues[i0])) {
				assertTrue(store.isMissing(i0), storeDiffersAt(i0));
				assertTrue(store.isMissing((long)i0), storeDiffersAt(i0));
			}
			else {
				assertFalse(store.isMissing(i0), storeDiffersAt(i0));
				assertFalse(store.isMissing((long)i0), storeDiffersAt(i0));
			}
		}
		assertIndexOutOfBounds(data, store::isMissing, store::isMissing);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void isNaN(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				assertFalse(store.isNaN(i0), storeDiffersAt(i0));
				assertFalse(store.isNaN((long)i0), storeDiffersAt(i0));
			}
			else if (Double.isNaN(data.realValues[i0])) {
				assertTrue(store.isNaN(i0), storeDiffersAt(i0));
				assertTrue(store.isNaN((long)i0), storeDiffersAt(i0));
			}
			else {
				assertFalse(store.isNaN(i0), storeDiffersAt(i0));
				assertFalse(store.isNaN((long)i0), storeDiffersAt(i0));
			}
		}
		assertIndexOutOfBounds(data, store::isNaN, store::isNaN);
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getLogi(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		assertUnsupported(data, store::getLogi, store::getLogi);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getInt(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		assertUnsupported(data, store::getInt, store::getInt);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getNum(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		assertUnsupported(data, store::getNum, store::getNum);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getCplx(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				// undefined
			}
			else {
				final double expectedRe= data.realValues[i0];
				final double expectedIm= data.imaginaryValues[i0];
				assertEquals(expectedRe, store.getCplxRe(i0), storeDiffersAt(i0));
				assertEquals(expectedRe, store.getCplxRe((long)i0), storeDiffersAt(i0));
				assertEquals(expectedIm, store.getCplxIm(i0), storeDiffersAt(i0));
				assertEquals(expectedIm, store.getCplxIm((long)i0), storeDiffersAt(i0));
			}
		}
		assertIndexOutOfBounds(data, store::getCplxRe, store::getCplxRe);
		assertIndexOutOfBounds(data, store::getCplxIm, store::getCplxIm);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getChar(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				// undefined
			}
			else {
				final String reStr= Double.toString(data.realValues[i0]).replace("Infinity", "Inf");
				final String imStr= Double.toString(data.imaginaryValues[i0]).replace("Infinity", "Inf");
				final String expected= (imStr.charAt(0) != '-') ?
						(reStr + '+' + imStr + 'i') :
						(reStr + imStr + 'i');
				assertEquals(expected, store.getChar(i0), storeDiffersAt(i0));
				assertEquals(expected, store.getChar((long)i0), storeDiffersAt(i0));
			}
		}
		assertIndexOutOfBounds(data, store::getChar, store::getChar);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getRaw(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		assertUnsupported(data, store::getRaw, store::getRaw);
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void get(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				assertNull(store.get(i0), storeDiffersAt(i0));
			}
			else {
				final Complex expected= new Complex(data.realValues[i0], data.imaginaryValues[i0]);
				assertEquals(expected, store.get(i0), storeDiffersAt(i0));
				assertEquals(expected, store.get((long)i0), storeDiffersAt(i0));
			}
		}
		assertIndexOutOfBounds(data, store::get, store::get);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void toArray(final CplxCaseData data) {
		final RComplexStore store= createStore(data);
		
		final @Nullable Complex[] array= store.toArray();
		
		assertEquals(data.realValues.length, array.length);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				assertNull(array[i0], arrayDiffersAt(i0));
			}
			else {
				final Complex expected= new Complex(data.realValues[i0], data.imaginaryValues[i0]);
				assertEquals(expected, array[i0], arrayDiffersAt(i0));
			}
		}
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void writeExternal(final CplxCaseData data) throws IOException {
		final RComplexStore store= createStore(data);
		
		if (store instanceof ExternalizableRStore) {
			final byte[] ser= writeExternal(store);
			assertArrayEquals(data.getExternalBytes(), ser);
		}
	}
	
}
