/*=============================================================================#
 # Copyright (c) 2009, 2019 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 java.util.Arrays;

import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.RStore;


public abstract class AbstractRStore<P> implements RStore<P> {
	
	
	protected static final long NA_numeric_LONG= 0x7ff80000000007a2L;
	protected static final long NA_numeric_LONG_MASK= 0x7ff00000ffffffffL;
	protected static final long NA_numeric_LONG_MATCH= 0x7ff00000000007a2L;
	protected static final int NA_numeric_INT_MATCH= 0x000007a2;
	protected static final double NA_numeric_DOUBLE= Double.longBitsToDouble(NA_numeric_LONG);
	protected static final long NaN_numeric_LONG= Double.doubleToLongBits(Double.NaN);
	protected static final double NaN_numeric_DOUBLE= Double.NaN;
	
	protected static final int NA_integer_INT= Integer.MIN_VALUE;
	
	protected static final byte NA_byte_BYTE= 0x0; // no real NA, used e.g. for new values
	
	protected static final byte FALSE_BYTE= 0;
	protected static final byte TRUE_BYTE= 1;
	protected static final byte NA_logical_BYTE= 2;
	
	protected static final int FALSE_INT= 0;
	protected static final int TRUE_INT= 1;
	protected static final int NA_logical_INT= Integer.MIN_VALUE;
	
	protected static final int WITH_NAMES= 0x1;
	
	protected static final byte[] EMPTY_BYTE_ARRAY= new byte[0];
	protected static final byte[][] EMPTY_BYTE_2dARRAY= new byte[0][];
	protected static final int[] EMPTY_INT_ARRAY= new int[0];
	protected static final int[][] EMPTY_INT_2dARRAY= new int[0][];
	protected static final double[] EMPTY_DOUBLE_ARRAY= new double[0];
	protected static final double[][] EMPTY_DOUBLE_2dARRAY= new double[0][];
	protected static final String[] EMPTY_STRING_ARRAY= new String[0];
	protected static final String[][] EMPTY_STRING_2dARRAY= new String[0][];
	
	protected static final int DEFAULT_LONG_DATA_SEGMENT_LENGTH= 1 << 28;
	
	
	private final static boolean gIsBSupported;
	static {
		gIsBSupported= checkIsBSupported();
	}
	
	public static boolean isBforNASupported() {
		return gIsBSupported;
	}
	
	private static boolean checkIsBSupported() {
		double d= 0;
		long l= 0;
		
		d= NA_numeric_DOUBLE;
		l= Double.doubleToRawLongBits(d);
		if (l != NA_numeric_LONG) {
			return false;
		}
		
		d= Double.longBitsToDouble(l);
		l= Double.doubleToRawLongBits(d);
		if (l != NA_numeric_LONG) {
			return false;
		}
		return true;
	}
	
	
	protected static final long check2dArrayLength(final int[][] array, final int segmentLength) {
		long length= 0;
		if (array.length > 0) {
			final int last= array.length - 1;
			for (int i= 0; i < last; i++) {
				if (array[i].length != segmentLength) {
					throw new IllegalArgumentException("Unexpected data segment length (" + array[i].length + ", but " + segmentLength + " expected)");
				}
			}
			length= last * (long) segmentLength;
			if (array[last].length > segmentLength) {
				throw new IllegalArgumentException("Unexpected data segment length (" + array[last].length + ", but max " + segmentLength + " expected)");
			}
			length+= array[last].length;
		}
		return length;
	}
	
	protected static final long check2dArrayLength(final double[][] array, final int segmentLength) {
		long length= 0;
		if (array.length > 0) {
			final int last= array.length - 1;
			for (int i= 0; i < last; i++) {
				if (array[i].length != segmentLength) {
					throw new IllegalArgumentException("Unexpected data segment length (" + array[i].length + ", but " + segmentLength + " expected)");
				}
			}
			length= last * (long) segmentLength;
			if (array[last].length > segmentLength) {
				throw new IllegalArgumentException("Unexpected data segment length (" + array[last].length + ", but max " + segmentLength + " expected)");
			}
			length+= array[last].length;
		}
		return length;
	}
	
	protected static final long check2dArrayLength(final byte[][] array, final int segmentLength) {
		long length= 0;
		if (array.length > 0) {
			final int last= array.length - 1;
			for (int i= 0; i < last; i++) {
				if (array[i].length != segmentLength) {
					throw new IllegalArgumentException("Unexpected data segment length (" + array[i].length + ", but " + segmentLength + " expected)");
				}
			}
			length= last * (long) segmentLength;
			if (array[last].length > segmentLength) {
				throw new IllegalArgumentException("Unexpected data segment length (" + array[last].length + ", but max " + segmentLength + " expected)");
			}
			length+= array[last].length;
		}
		return length;
	}
	
	protected static final long check2dArrayLength(final Object[][] array, final int segmentLength) {
		long length= 0;
		if (array.length > 0) {
			final int last= array.length - 1;
			for (int i= 0; i < last; i++) {
				if (array[i].length != segmentLength) {
					throw new IllegalArgumentException("Unexpected data segment length (" + array[i].length + ", but " + segmentLength + " expected)");
				}
			}
			length= last * (long) segmentLength;
			if (array[last].length > segmentLength) {
				throw new IllegalArgumentException("Unexpected data segment length (" + array[last].length + ", but max " + segmentLength + " expected)");
			}
			length+= array[last].length;
		}
		return length;
	}
	
	protected static final int[][] new2dIntArray(final long length, final int segmentLength) {
		if (length == 0) {
			return EMPTY_INT_2dARRAY;
		}
		final int[][] array= new int[1 + (int) ((length - 1) / segmentLength)][];
		final int last= array.length - 1;
		for (int i= 0; i < last; i++) {
			array[i]= new int[segmentLength];
		}
		{	final int restLength= (int) (length % segmentLength);
		array[last]= new int[(restLength == 0) ? segmentLength : restLength];
		}
		return array;
	}
	
	protected static final double[][] new2dDoubleArray(final long length, final int segmentLength) {
		if (length == 0) {
			return EMPTY_DOUBLE_2dARRAY;
		}
		final double[][] array= new double[1 + (int) ((length - 1) / segmentLength)][];
		final int last= array.length - 1;
		for (int i= 0; i < last; i++) {
			array[i]= new double[segmentLength];
		}
		{	final int restLength= (int) (length % segmentLength);
			array[last]= new double[(restLength == 0) ? segmentLength : restLength];
		}
		return array;
	}
	
	protected static final String[][] new2dStringArray(final long length, final int segmentLength) {
		if (length == 0) {
			return EMPTY_STRING_2dARRAY;
		}
		final String[][] array= new String[1 + (int) ((length - 1) / segmentLength)][];
		final int last= array.length - 1;
		for (int i= 0; i < last; i++) {
			array[i]= new String[segmentLength];
		}
		{	final int restLength= (int) (length % segmentLength);
			array[last]= new String[(restLength == 0) ? segmentLength : restLength];
		}
		return array;
	}
	
	protected static final byte[][] new2dByteArray(final long length, final int segmentLength) {
		if (length == 0) {
			return EMPTY_BYTE_2dARRAY;
		}
		final byte[][] array= new byte[1 + (int) ((length - 1) / segmentLength)][];
		final int last= array.length - 1;
		for (int i= 0; i < last; i++) {
			array[i]= new byte[segmentLength];
		}
		{	final int restLength= (int) (length % segmentLength);
		array[last]= new byte[(restLength == 0) ? segmentLength : restLength];
		}
		return array;
	}
	
	
	protected static final int[] addIdx(final int[] idxs, final int newIdx) {
		int i= Arrays.binarySearch(idxs, newIdx);
		if (i >= 0) {
			return idxs;
		}
		final int[] newIdxs= new int[idxs.length+1];
		i= -1-i;
		System.arraycopy(idxs, 0, newIdxs, 0, i);
		newIdxs[i]= newIdx;
		System.arraycopy(idxs, i, newIdxs, i+1, idxs.length-i);
		return newIdxs;
	}
	
	protected static final int[] insertIdx(final int[] currentIdxs, final int[] insertedIdxs) {
		final int[] pos= new int[insertedIdxs.length];
		for (int i= 0; i < pos.length; i++) {
			pos[i]= Arrays.binarySearch(currentIdxs, insertedIdxs[i]);
			if (pos[i] < 0) {
				pos[i]= -1-pos[i];
			}
		}
		final int[] newIdxs= new int[currentIdxs.length+insertedIdxs.length];
		int l= pos.length;
		int ci= currentIdxs.length-1;
		while(l > 1) {
			final int stop= pos[l-1];
			for (; ci >= stop; ci--) {
				newIdxs[ci+l]= currentIdxs[ci] + l;
			}
			l--;
			newIdxs[ci+l]= insertedIdxs[l] + l;
		}
		System.arraycopy(currentIdxs, 0, newIdxs, 0, pos[0]);
		return newIdxs;
	}
	
	protected static final void updateIdxInserted(final int[] currentIdxs, final int[] insertedIdxs) {
		int pos= Arrays.binarySearch(currentIdxs, insertedIdxs[0]);
		if (pos < 0) {
			pos= -1-pos;
		}
		for (int i= 0; i < insertedIdxs.length; ) {
			i++;
			int stop= (i < insertedIdxs.length) ? Arrays.binarySearch(currentIdxs, insertedIdxs[i]) : currentIdxs.length;
			if (stop < 0) {
				stop= -1-stop;
			}
			while (pos < stop) {
				currentIdxs[pos]+= i;
			}
			pos= stop;
		}
	}
	
	protected static final int[] updateIdxRemoved(final int[] currentIdxs, final int[] removedIdxs) {
		final int[] pos= new int[removedIdxs.length];
		int naCount= 0;
		for (int i= 0; i < pos.length; i++) {
			pos[i]= Arrays.binarySearch(currentIdxs, removedIdxs[i]);
			if (pos[i] < 0) {
				pos[i]= -1-pos[i];
			}
			else {
				naCount++;
			}
		}
		final int[] newIdxs= (naCount == 0) ? currentIdxs : new int[currentIdxs.length-naCount];
		int l= 0;
		int ci= 0;
		int ni= 0;
		if (newIdxs != currentIdxs) {
			System.arraycopy(currentIdxs, 0, newIdxs, 0, pos[0]);
		}
		while(l < removedIdxs.length) {
			if (currentIdxs[pos[l]] == removedIdxs[l]) {
				ci++;
			}
			l++;
			final int stop= (l < removedIdxs.length) ? pos[l] : currentIdxs.length;
			for (; ci < stop; ci++, ni++) {
				newIdxs[ni]= currentIdxs[ci] - l;
			}
		}
		return newIdxs;
	}
	
	protected static final int[] deleteIdx(final int[] idxs, final int removeIdx) {
		final int i= Arrays.binarySearch(idxs, removeIdx);
		if (i < 0) {
			return idxs;
		}
		final int[] newIdxs= new int[idxs.length-1];
		System.arraycopy(idxs, 0, newIdxs, 0, i);
		System.arraycopy(idxs, i+1, newIdxs, i, idxs.length-i-1);
		return newIdxs;
	}
	
	protected static final int getNewArraySize(final int length) {
		if (length >= 0xfffffff) {
			return Integer.MAX_VALUE;
		}
		return ((length+0x7) | 0xf) + 1;
	}
	
	protected static final double[] ensureCapacity(final double[] currentValues, final int length) {
		if (currentValues.length >= length) {
			return currentValues;
		}
		return new double[getNewArraySize(length)];
	}
	
	protected static final int[] ensureCapacity(final int[] currentValues, final int length) {
		final int diff= currentValues.length - length;
		if (diff >= 0 && diff <= 512) {
			return currentValues;
		}
		return new int[getNewArraySize(length)];
	}
	
	protected static final byte[] ensureCapacity(final byte[] currentValues, final int length) {
		if (currentValues.length >= length) {
			return currentValues;
		}
		return new byte[getNewArraySize(length)];
	}
	
	protected static final String[] ensureCapacity(final String[] currentValues, final int length) {
		if (currentValues.length >= length) {
			return currentValues;
		}
		return new String[getNewArraySize(length)];
	}
	
	protected static final double[] prepareInsert(final double[] currentValues, final int currentLength, final int[] idxs) {
		final double[] newValues= ensureCapacity(currentValues, currentLength+idxs.length);
		int i= idxs.length-1;
		System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, currentLength-idxs[i]);
		for (i--; i >= 0; i--) {
			System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, idxs[i+1]-idxs[i]);
		}
		if (newValues != currentValues) {
			System.arraycopy(currentValues, 0, newValues, 0, idxs[0]);
		}
		return newValues;
	}
	
	protected static final int[] prepareInsert(final int[] currentValues, final int currentLength, final int[] idxs) {
		final int[] newValues= ensureCapacity(currentValues, currentLength+idxs.length);
		int i= idxs.length-1;
		System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, currentLength-idxs[i]);
		for (i--; i >= 0; i--) {
			System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, idxs[i+1]-idxs[i]);
		}
		if (newValues != currentValues) {
			System.arraycopy(currentValues, 0, newValues, 0, idxs[0]);
		}
		return newValues;
	}
	
	protected static final byte[] prepareInsert(final byte[] currentValues, final int currentLength, final int[] idxs) {
		final byte[] newValues= ensureCapacity(currentValues, currentLength+idxs.length);
		int i= idxs.length-1;
		System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, currentLength-idxs[i]);
		for (i--; i >= 0; i--) {
			System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, idxs[i+1]-idxs[i]);
		}
		if (currentValues != newValues) {
			System.arraycopy(currentValues, 0, newValues, 0, idxs[0]);
		}
		return newValues;
	}
	
	protected static final String[] prepareInsert(final String[] currentValues, final int currentLength, final int[] idxs) {
		final String[] newValues= ensureCapacity(currentValues, currentLength+idxs.length);
		int i= idxs.length-1;
		System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, currentLength-idxs[i]);
		for (i--; i >= 0; i--) {
			System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, idxs[i+1]-idxs[i]);
		}
		if (currentValues != newValues) {
			System.arraycopy(currentValues, 0, newValues, 0, idxs[0]);
		}
		return newValues;
	}
	
	protected static final double[] remove(final double[] currentValues, final int currentLength, final int[] idxs) {
		final double[] newValues= ensureCapacity(currentValues, currentLength-idxs.length);
		if (currentValues != newValues) {
			System.arraycopy(currentValues, 0, newValues, 0, idxs[0]);
		}
		int i= 0;
		for (; i < idxs.length-1; i++) {
			System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, idxs[i+1]-idxs[i]);
		}
		System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, currentLength-idxs[i]-1);
		return newValues;
	}
	
	protected static final int[] remove(final int[] currentValues, final int currentLength, final int[] idxs) {
		final int[] newValues= ensureCapacity(currentValues, currentLength-idxs.length);
		if (currentValues != newValues) {
			System.arraycopy(currentValues, 0, newValues, 0, idxs[0]);
		}
		int i= 0;
		for (; i < idxs.length-1; i++) {
			System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, idxs[i+1]-idxs[i]);
		}
		System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, currentLength-idxs[i]-1);
		return newValues;
	}
	
	protected static final byte[] remove(final byte[] currentValues, final int currentLength, final int[] idxs) {
		final byte[] newValues= ensureCapacity(currentValues, currentLength-idxs.length);
		if (currentValues != newValues) {
			System.arraycopy(currentValues, 0, newValues, 0, idxs[0]);
		}
		int i= 0;
		for (; i < idxs.length-1; i++) {
			System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, idxs[i+1]-idxs[i]);
		}
		System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, currentLength-idxs[i]-1);
		return newValues;
	}
	
	protected static final String[] remove(final String[] currentValues, final int currentLength, final int[] idxs) {
		final String[] newValues= ensureCapacity(currentValues, currentLength-idxs.length);
		if (currentValues != newValues) {
			System.arraycopy(currentValues, 0, newValues, 0, idxs[0]);
		}
		int i= 0;
		for (; i < idxs.length-1; i++) {
			System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, idxs[i+1]-idxs[i]);
		}
		System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, currentLength-idxs[i]-1);
		return newValues;
	}
	
	
	@Override
	public void setNA(final int idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setNA(final long idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public boolean getLogi(final int idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public boolean getLogi(final long idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setLogi(final int idx, final boolean logi) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setLogi(final long idx, final boolean logi) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public int getInt(final int idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public int getInt(final long idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setInt(final int idx, final int integer) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setInt(final long idx, final int integer) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public double getNum(final int idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public double getNum(final long idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setNum(final int idx, final double real) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setNum(final long idx, final double real) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public String getChar(final int idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public String getChar(final long idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setChar(final int idx, final String character) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setChar(final long idx, final String character) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public byte getRaw(final int idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public byte getRaw(final long idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setRaw(final int idx, final byte raw) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setRaw(final long idx, final byte raw) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public double getCplxIm(final int idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public double getCplxIm(final long idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public double getCplxRe(final int idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public double getCplxRe(final long idx) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setCplx(final int idx, final double real, final double imaginary) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public void setCplx(final long idx, final double real, final double imaginary) {
		throw new UnsupportedOperationException();
	}
	
	
	protected abstract boolean isStructOnly();
	
	
	@Override
	public boolean containsNA() {
		return (indexOfNA(0) >= 0);
	}
	
	@Override
	public long indexOfNA() {
		return indexOfNA(0);
	}
	
	@Override
	public long indexOfNA(long fromIdx) {
		if (fromIdx < 0) {
			fromIdx= 0;
		}
		final long length= getLength();
		while (fromIdx < length) {
			if (isNA(fromIdx)) {
				return fromIdx;
			}
			fromIdx++;
		}
		return -1;
	}
	
	@Override
	public boolean contains(final int integer) {
		return (indexOf(integer, 0) >= 0);
	}
	
	@Override
	public final long indexOf(final int integer) {
		return indexOf(integer, 0);
	}
	
	@Override
	public long indexOf(final int integer, long fromIdx) {
		if (fromIdx < 0) {
			fromIdx= 0;
		}
		final long l= getLength();
		while (fromIdx < l) {
			if (!isNA(fromIdx) && integer == getInt(fromIdx)) {
				return fromIdx;
			}
			fromIdx++;
		}
		return -1;
	}
	
	@Override
	public boolean contains(final String character) {
		return (indexOf(character, 0) >= 0);
	}
	
	@Override
	public final long indexOf(final String character) {
		return indexOf(character, 0);
	}
	
	@Override
	public long indexOf(final String character, long fromIdx) {
		if (character == null) {
			return -1;
		}
		if (fromIdx < 0) {
			fromIdx= 0;
		}
		final long l= getLength();
		while (fromIdx < l) {
			if (!isNA(fromIdx) && character.equals(getChar(fromIdx))) {
				return fromIdx;
			}
			fromIdx++;
		}
		return -1;
	}
	
	
	protected int checkToArrayLength() {
		final long length= getLength();
		if (length > Integer.MAX_VALUE) {
			throw new UnsupportedOperationException("Not supported for long data");
		}
		return (int) length;
	}
	
	
	@Override
	public String toString() {
		final StringBuilder sb= new StringBuilder();
		sb.append(RDataUtils.getStoreAbbr(this));
		sb.append(' ');
		final long length;
		if (isStructOnly()) {
			sb.append("<struct only>");
		}
		else if ((length= getLength()) > 0) {
			long end= (length <= 25) ? length : 10;
			if (getStoreType() == CHARACTER) {
				for (long idx= 0; true;) {
					if (isNA(idx)) {
						sb.append("NA");
					}
					else {
						sb.append('"');
						sb.append(getChar(idx));
						sb.append('"');
					}
					idx++;
					if (idx < end) {
						sb.append(", ");
						continue;
					}
					else {
						if (end == length) {
							break;
						}
						else {
							sb.append(", .., ");
							idx= length - 10;
							end= length;
							continue;
						}
					}
				}
			}
			else {
				for (long idx= 0; true;) {
					if (isNA(idx)) {
						sb.append("NA");
					}
					else {
						sb.append(getChar(idx));
					}
					idx++;
					if (idx < end) {
						sb.append(", ");
						continue;
					}
					else {
						if (end == length) {
							break;
						}
						else {
							sb.append(", .., ");
							idx= length - 10;
							end= length;
							continue;
						}
					}
				}
			}
		}
		return sb.toString();
	}
	
}
