/*=============================================================================#
 # 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.assertNull;

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.RLogicalStore;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RStore;


@NonNullByDefault
public abstract class RLogicalStoreTest extends AbstractRStoreTest {
	
	
	static class LogiCaseData extends CaseData<RLogicalStore> {
		
		final static Function<LogiCaseData, RLogicalStore> REF_CONSTRUCTOR= new RLogicalByte32StoreTest()::createStore;
		
		final boolean[] values;
		
		
		public LogiCaseData(final String label, final boolean[] values, final boolean[] nas) {
			super(label, nas);
			assert (values.length == this.length);
			assert (nas.length == this.length);
			this.values= values;
			
			setReference(REF_CONSTRUCTOR.apply(this));
		}
		
		public LogiCaseData(final String label, final boolean[] values) {
			super(label, values.length);
			assert (values.length == this.length);
			this.values= values;
			
			setReference(REF_CONSTRUCTOR.apply(this));
		}
		
	}
	
	protected static final List<LogiCaseData> DEFAULT_DATA_SOURCES;
	static {
		final var datas= new ArrayList<LogiCaseData>();
		
		datas.add(new LogiCaseData("empty", new boolean[0]));
		
		datas.add(new LogiCaseData("single-TRUE", new boolean[] { true }));
		datas.add(new LogiCaseData("single-FALSE", new boolean[] { false }));
		datas.add(new LogiCaseData("single-NA", new boolean[] { false }, new boolean[] { true }));
		
		{	final boolean[] values= new boolean[0xFF];
			final boolean[] nas= new boolean[values.length];
			int i= 0;
			values[i++]= false;
			values[i++]= true;
			nas[i++]= true;
			for (; i < values.length; i++) {
				values[i]= (i % 2 == 0);
			}
			datas.add(new LogiCaseData("special", values, nas));
		}
		
		{	final Random rand= new Random(16857);
			final boolean[] values= new boolean[100000];
			for (int i= 0; i < values.length; i++) {
				values[i]= rand.nextBoolean();
			}
			datas.add(new LogiCaseData("rand100000", values));
		}
		if (isBigDataEnabled(1)) {
			final Random rand= new Random(46);
			final boolean[] values= new boolean[DEFAULT_LONG_DATA_SEGMENT_LENGTH * 2 + 13];
			for (int i= 0; i < values.length; i++) {
				values[i]= rand.nextBoolean();
			}
			datas.add(new LogiCaseData("randMultiSeg", values));
		}
		
		DEFAULT_DATA_SOURCES= datas;
	}
	
	
	public RLogicalStoreTest() {
	}
	
	
	public static List<LogiCaseData> provideCaseDatas() {
		return new ArrayList<>(DEFAULT_DATA_SOURCES);
	}
	
	protected abstract RLogicalStore createStore(final LogiCaseData data);
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getStoreType(final LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		assertEquals(RStore.LOGICAL, store.getStoreType());
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getBaseVectorRClassName(final LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		assertEquals(RObject.CLASSNAME_LOGICAL, store.getBaseVectorRClassName());
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void length(final LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		checkLength(data, store);
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void isNA(final LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		checkIsNA(data, store);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void isMissing(final LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		checkIsMissingNonNum(data, store);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	@SuppressWarnings("boxing")
	public void getLogi(final LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				// undefined
			}
			else {
				final Boolean expected= Boolean.valueOf(data.values[i0]);
				assertEquals(expected, store.getLogi(i0));
				assertEquals(expected, store.getLogi((long)i0));
			}
		}
		assertIndexOutOfBounds(data, store::getLogi, store::getLogi);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getInt(final LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				// undefined
			}
			else {
				final int expected= (data.values[i0]) ? 1 : 0;
				assertEquals(expected, store.getInt(i0));
				assertEquals(expected, store.getInt((long)i0));
			}
		}
		assertIndexOutOfBounds(data, store::getInt, store::getInt);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getNum(final LogiCaseData data) {
//		final RLogicalStore store= createStore(data);
//		
//		for (int i= 0; i < data.length; i++) {
//			final int i0= i;
//			if (data.nas[i0]) {
//				// undefined
//			}
//			else {
//				final double expected= (data.values[i0]) ? 1.0 : 0.0;
//				assertEquals(expected, store.getNum(i0));
//				assertEquals(expected, store.getNum((long)i0));
//			}
//		}
//		assertIndexOutOfBounds(data, store::getNum, store::getNum);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getChar(final LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				// undefined
			}
			else {
				final String expected= (data.values[i0]) ? "TRUE" : "FALSE";
				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 LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				// undefined
			}
			else {
				final byte expected= (data.values[i0]) ? (byte)1 : (byte)0;
				assertEquals(expected, store.getRaw(i0), storeDiffersAt(i0));
				assertEquals(expected, store.getRaw((long)i0), storeDiffersAt(i0));
			}
		}
		assertIndexOutOfBounds(data, store::getRaw, store::getRaw);
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void get(final LogiCaseData data) {
		final RLogicalStore 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 Boolean expected= Boolean.valueOf(data.values[i0]);
				assertEquals(expected, store.get(i0));
				assertEquals(expected, store.get((long)i0));
			}
		}
		assertIndexOutOfBounds(data, store::get, store::get);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void toArray(final LogiCaseData data) {
		final RLogicalStore store= createStore(data);
		
		final @Nullable Boolean[] array= store.toArray();
		
		assertEquals(data.values.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 Boolean expected= Boolean.valueOf(data.values[i0]);
				assertEquals(expected, array[i0], arrayDiffersAt(i0));
			}
		}
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void writeExternal(final LogiCaseData data) throws IOException {
		final RLogicalStore store= createStore(data);
		
		if (store instanceof ExternalizableRStore) {
			final byte[] ser= writeExternal(store);
			assertArrayEquals(data.getExternalBytes(), ser);
		}
	}
	
}
