/*=============================================================================#
 # 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.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;

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.LinkedHashMap;
import java.util.List;
import java.util.Map;
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.RCharacterStore;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RStore;


@NonNullByDefault
public abstract class RCharacterStoreTest extends AbstractRStoreTest {
	
	
	static class CharCaseData extends CaseData<RCharacterStore> {
		
		static final Function<CharCaseData, RCharacterStore> REF_CONSTRUCTOR= new RCharacter32StoreTest()::createStore;
		
		final String[] values;
		
		
		public CharCaseData(final String label, final String[] 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 CharCaseData(final String label, final String[] values) {
			super(label, values.length);
			assert (values.length == this.length);
			this.values= values;
			
			setReference(REF_CONSTRUCTOR.apply(this));
		}
		
	}
	
	
	private static final Map<String, Boolean> LOGI_STRINGS;
	static {
		final var map= new LinkedHashMap<String, Boolean>();
		for (final String s : List.<String>of("T", "TRUE", "True", "true")) {
			map.put(s, Boolean.TRUE);
		}
		for (final String s : List.<String>of("F", "FALSE", "False", "false")) {
			map.put(s, Boolean.FALSE);
		}
		LOGI_STRINGS= map;
	}
	
	protected static final List<CharCaseData> DEFAULT_DATA_SOURCES;
	static {
		final var datas= new ArrayList<CharCaseData>();
		
		datas.add(new CharCaseData("empty", new @Nullable String[0]));
		
		datas.add(new CharCaseData("single-empty", new String[] { "" }));
		datas.add(new CharCaseData("single-1", new String[] { "1" }));
		datas.add(new CharCaseData("single", new String[] { "abcdefghijkl" }));
		datas.add(new CharCaseData("single-NA", new String[] { null }, new boolean[] { true }));
		
		{	final String[] values= new String[LOGI_STRINGS.size() + 3];
			final boolean[] nas= new boolean[values.length];
			int i= 0;
			for (final String string : LOGI_STRINGS.keySet()) {
				values[i++]= string;
			}
			values[i++]= "TRue";
			values[i++]= "falsE";
			nas[i++]= true;
			datas.add(new CharCaseData("logi", values, nas));
		}
		
		{	final Random rand= new Random(16857);
			final String[] values= new String[100000];
			for (int i= 0; i < values.length; i++) {
				values[i]= Integer.toString(rand.nextInt());
			}
			datas.add(new CharCaseData("rand100000", values));
		}
		if (isBigDataEnabled(64)) {
			final Random rand= new Random(46);
			final String[] values= new String[DEFAULT_LONG_DATA_SEGMENT_LENGTH * 2 + 13];
			for (int i= 0; i < values.length; i++) {
				values[i]= Integer.toHexString(rand.nextInt());
			}
			datas.add(new CharCaseData("randMultiSeg", values));
		}
		
		DEFAULT_DATA_SOURCES= datas;
	}
	
	
	public RCharacterStoreTest() {
	}
	
	
	public static List<CharCaseData> provideCaseDatas() {
		return new ArrayList<>(DEFAULT_DATA_SOURCES);
	}
	
	protected abstract RCharacterStore createStore(final CharCaseData data);
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getStoreType(final CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		assertEquals(RStore.CHARACTER, store.getStoreType());
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getBaseVectorRClassName(final CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		assertEquals(RObject.CLASSNAME_CHARACTER, store.getBaseVectorRClassName());
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void length(final CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		checkLength(data, store);
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void isNA(final CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		checkIsNA(data, store);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void isMissing(final CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		checkIsMissingNonNum(data, store);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	@SuppressWarnings("boxing")
	public void getLogi(final CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			try {
				if (data.nas[i0]) {
					// undefined
				}
				else {
					final Boolean logi= LOGI_STRINGS.get(data.values[i0]);
					if (logi != null) {
						final boolean expected= logi.booleanValue();
						assertEquals(expected, store.getLogi(i0), storeDiffersAt(i0));
						assertEquals(expected, store.getLogi((long)i0), storeDiffersAt(i0));
					}
					else {
						assertThrows(NumberFormatException.class, () -> store.getLogi(i0), storeDiffersAt(i0));
						assertThrows(NumberFormatException.class, () -> store.getLogi((long)i0), storeDiffersAt(i0));
					}
				}
			}
			catch (final NumberFormatException e) {
				fail(storeDiffersAt(i0).get(), e);
			}
		}
		assertIndexOutOfBounds(data, store::getLogi, store::getLogi);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getInt(final CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		assertUnsupported(data, store::getInt, store::getInt);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getNum(final CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		assertUnsupported(data, store::getNum, store::getNum);
	}
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void getChar(final CharCaseData data) {
		final RCharacterStore 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];
				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 CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		assertUnsupported(data, store::getRaw, store::getRaw);
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void get(final CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		for (int i= 0; i < data.length; i++) {
			final int i0= i;
			if (data.nas[i0]) {
				assertNull(store.get(i), storeDiffersAt(i0));
			}
			else {
				final String expected= 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 CharCaseData data) {
		final RCharacterStore store= createStore(data);
		
		final @Nullable String[] 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(store.get(i), arrayDiffersAt(i0));
			}
			else {
				final String expected= data.values[i0];
				assertEquals(expected, array[i], arrayDiffersAt(i0));
			}
		}
	}
	
	
	@ParameterizedTest
	@MethodSource("provideCaseDatas")
	public void writeExternal(final CharCaseData data) throws IOException {
		final RCharacterStore store= createStore(data);
		
		if (store instanceof ExternalizableRStore) {
			final byte[] ser= writeExternal(store);
			assertArrayEquals(data.getExternalBytes(), ser);
		}
	}
	
}
