/*=============================================================================#
 # 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.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.util.ArrayList;
import java.util.List;
import java.util.Random;

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 {
		
		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;
		}
		
		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;
		}
		
	}
	
	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 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));
			}
		}
	}
	
}
