/*=============================================================================#
 # Copyright (c) 2010, 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.internal.r.debug.core.model;

import static org.eclipse.statet.internal.r.debug.core.model.RElementVariable.DEFAULT_FRAGMENT_COUNT;

import java.util.Objects;

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IVariable;

import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;

import org.eclipse.statet.ecommons.debug.core.model.VariablePartitionFactory;

import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.data.RValueFormatter;
import org.eclipse.statet.r.core.data.RValueValidator;
import org.eclipse.statet.r.debug.core.IRVariable;
import org.eclipse.statet.rj.data.RStore;
import org.eclipse.statet.rj.data.RVector;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
import org.eclipse.statet.rj.services.FQRObjectRef;
import org.eclipse.statet.rj.services.util.dataaccess.LazyRStore;
import org.eclipse.statet.rj.services.util.dataaccess.LazyRStore.Fragment;
import org.eclipse.statet.rj.services.util.dataaccess.RDataAssignment;
import org.eclipse.statet.rj.services.util.dataaccess.RVectorDataAdapter;
import org.eclipse.statet.rj.ts.core.RToolService;


@NonNullByDefault
public class RVectorValue extends RElementVariableValue<CombinedRElement> implements IRIndexValueInternal {
	
	
	private static final RVectorDataAdapter ADAPTER= new RVectorDataAdapter();
	
	
	public static final int LOAD_SIZE= 1000;
	
	
	final long length;
	
	private @Nullable LazyRStore<RVector<?>> namesStore;
	private @Nullable LazyRStore<RVector<?>> dataStore;
	
	
	public RVectorValue(final RElementVariable variable) {
		super(variable);
		
		final RVector<?> element= getRObject();
		this.length= element.getLength();
	}
	
	
	public final RVector<?> getRObject() {
		return (RVector<?>) this.element;
	}
	
	
	public boolean hasValueChanged(final long index) {
		final RVectorValue previousValue;
		synchronized (this.variable) {
			if (this != this.variable.getCurrentValue()) {
				return false;
			}
			previousValue= (RVectorValue) this.variable.getPreviousValue();
		}
		
		if (previousValue != null) {
			if (index >= previousValue.length) {
				return true;
			}
			final LazyRStore.Fragment<RVector<?>> previousFragment;
			final LazyRStore.Fragment<RVector<?>> currentFragment;
			synchronized (previousValue) {
				previousFragment= previousValue.getLoadedDataFragment(index);
				if (previousFragment == null || previousFragment.getRObject() == null) {
					return false;
				}
			}
			synchronized (this) {
				currentFragment= getDataFragment(index);
				if (currentFragment == null || currentFragment.getRObject() == null) {
					return false;
				}
			}
			return (!Objects.equals(
					currentFragment.getRObject().getData().get(
							currentFragment.toLocalRowIdx(index) ),
					previousFragment.getRObject().getData().get(
							previousFragment.toLocalRowIdx(index) )));
		}
		return false;
	}
	
	
	@Override
	public String getValueString() throws DebugException {
		if (this.length == 0) {
			return ""; //$NON-NLS-1$
		}
		else if (this.length == 1) {
			final String data= getDataExpr(0);
			if (data == null) {
				throw newRequestLoadDataFailed();
			}
			return data;
		}
		else {
			return "[" + this.length + ']'; //$NON-NLS-1$
		}
	}
	
	@Override
	public String getDetailString() {
		if (this.length == 0) {
			return ""; //$NON-NLS-1$
		}
		else if (this.length == 1) {
			final String data= getDataExpr(0);
			if (data == null) {
				return "<error>"; //$NON-NLS-1$
			}
			return data;
		}
		return ""; //$NON-NLS-1$
	}
	
	
	@Override
	public boolean hasVariables() throws DebugException {
		return (this.length > 1);
	}
	
	@Override
	public IVariable[] getVariables() throws DebugException {
		if (this.length <= 1) {
			return NO_VARIABLES;
		}
		return getPartitionFactory().getVariables(this);
	}
	
	
	@Override
	public VariablePartitionFactory<IRIndexElementValue> getPartitionFactory() {
		return RElementVariableValue.PARTITION_FACTORY;
	}
	
	@Override
	public long getSize() throws DebugException {
		return this.length;
	}
	
	@Override
	public IRVariable[] getVariables(final long offset, final int length) {
		return getVariables(offset, length, this.variable);
	}
	
	@Override
	public IRVariable[] getVariables(final long offset, final int length, final IRVariable parent) {
		if (this.length <= 1) {
			throw new UnsupportedOperationException();
		}
		if (offset < 0 || length < 0 || offset > this.length - length) {
			throw new IllegalArgumentException();
		}
		final @NonNull IRVariable[] variables= new @NonNull IRVariable[length];
		for (int i= 0; i < length; i++) {
			variables[i]= new RVectorIndexVariable(this, offset + i, parent);
		}
		return variables;
	}
	
	
	protected @Nullable String getName(final long idx) {
		synchronized (this.variable) {
			if (this != this.variable.getCurrentValue()) {
				return null;
			}
		}
		
		final LazyRStore.Fragment<RVector<?>> fragment;
		synchronized (this) {
			fragment= getNamesFragment(idx);
			if (fragment == null || fragment.getRObject() == null) {
				return null;
			}
		}
		
		final RValueFormatter formatter= getDebugTarget().getValueFormatter();
		synchronized (formatter) {
			return formatter.formatName(
					fragment.getRObject().getNames(), (int) fragment.toLocalRowIdx(idx) );
		}
	}
	
	private @Nullable Fragment<RVector<?>> getNamesFragment(final long idx) {
		if (this.namesStore == null) {
			this.namesStore= new LazyRStore<>(this.length, 1,
					DEFAULT_FRAGMENT_COUNT,
					new RDataLoader<RVector<?>>() {
				@Override
				protected RVector<?> doLoad(final FQRObjectRef ref,
						final Fragment<RVector<?>> fragment,
						final RToolService r, final ProgressMonitor m) throws StatusException, UnexpectedRDataException {
					return ADAPTER.loadRowNames(ref, getRObject(), fragment, null,
							r, m );
				}
			});
		}
		return this.namesStore.getFragment(idx, 0, 0, null);
	}
	
	
	protected final @Nullable RStore<?> getValueType() {
		RStore<?> data= this.element.getData();
		if (data.getStoreType() == RStore.FACTOR) {
			synchronized (this) {
				final Fragment<RVector<?>> fragment= getDataFragmentAny();
				if (fragment == null || fragment.getRObject() == null) {
					return null;
				}
				data= fragment.getRObject().getData();
			}
		}
		return data;
	}
	
	protected @Nullable String getDataExpr(final long idx) {
		synchronized (this.variable) {
			if (this != this.variable.getCurrentValue()) {
				return null;
			}
		}
		
		final LazyRStore.Fragment<RVector<?>> fragment;
		synchronized (this) {
			fragment= getDataFragment(idx);
			if (fragment == null || fragment.getRObject() == null) {
				return null;
			}
		}
		
		final RValueFormatter formatter= getDebugTarget().getValueFormatter();
		synchronized (formatter) {
			return formatter.format(
					fragment.getRObject().getData(), (int) fragment.toLocalRowIdx(idx) );
		}
	}
	
	protected boolean validateDataExpr(final String expression) {
		synchronized (this.variable) {
			if (this != this.variable.getCurrentValue()) {
				return false;
			}
		}
		
		final RStore<?> type= getValueType();
		final RValueValidator validator= getDebugTarget().getValueValidator();
		synchronized (validator) {
			return validator.isValid(type, expression);
		}
	}
	
	protected void setDataExpr(final long idx, final String expression) throws DebugException {
		synchronized (this.variable) {
			if (this != this.variable.getCurrentValue()) {
				throw newRequestSetDataFailed();
			}
		}
		
		final RStore<?> type= getValueType();
		final RStore<?> data;
		final RValueValidator validator= getDebugTarget().getValueValidator();
		synchronized (validator) {
			data= validator.toRData(type, expression);
		}
		if (data == null) {
			throw newNotSupported();
		}
		
		final RDataAssignment assignment= new RDataAssignment(idx, 0, data);
		synchronized (this) {
			setData(assignment);
		}
	}
	
	private LazyRStore<RVector<?>> ensureDataStore() {
		if (this.dataStore == null) {
			this.dataStore= new LazyRStore<>(this.length, 1,
					DEFAULT_FRAGMENT_COUNT,
					new RDataLoader<RVector<?>>() {
				@Override
				protected void doSet(final FQRObjectRef ref,
						final RDataAssignment assignment,
						final RToolService r, final ProgressMonitor m) throws StatusException, UnexpectedRDataException {
					ADAPTER.setData(ref, getRObject(), assignment, null,
							r, m );
				}
				@Override
				protected RVector<?> doLoad(final FQRObjectRef ref,
						final Fragment<RVector<?>> fragment,
						final RToolService r, final ProgressMonitor m) throws StatusException, UnexpectedRDataException {
					return ADAPTER.loadData(ref, getRObject(), fragment, null,
							r, m );
				}
			});
		}
		return this.dataStore;
	}
	
	private @Nullable Fragment<RVector<?>> getDataFragment(final long idx) {
		return ensureDataStore().getFragment(idx, 0, 0, null);
	}
	
	private @Nullable Fragment<RVector<?>> getDataFragmentAny() {
		final LazyRStore<RVector<?>> dataStore= ensureDataStore();
		Fragment<RVector<?>> fragment= dataStore.getLoadedFragmentAny();
		if (fragment == null) {
			fragment= dataStore.getLoadedFragment(0, 0);
		}
		return fragment;
	}
	
	private @Nullable Fragment<RVector<?>> getLoadedDataFragment(final long idx) {
		return (this.dataStore != null) ?
				this.dataStore.getLoadedFragment(idx, 0) :
				null;
	}
	
	public void setData(final RDataAssignment assignment) {
		ensureDataStore().set(assignment, 0, null);
		
		this.variable.fireChangeEvent(DebugEvent.CONTENT);
	}
	
}
