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

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IValue;

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.internal.r.debug.core.RDebugCorePlugin;
import org.eclipse.statet.r.console.core.RProcessREnvironment;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.debug.core.IRElementVariable;
import org.eclipse.statet.r.debug.core.IRValue;
import org.eclipse.statet.r.debug.core.IRVariable;
import org.eclipse.statet.rj.data.RArray;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RReference;


@NonNullByDefault
public final class RElementVariable extends RVariable implements IRElementVariable {
	
	
	public static final int DEFAULT_FRAGMENT_COUNT= 100;
	
	
	public static @Nullable RElementName createFQElementName(IRVariable variable) {
		final List<RElementName> segments= new ArrayList<>();
		byte lastRType= 0;
		do {
			if (variable instanceof IRElementVariable) {
				final CombinedRElement element= ((IRElementVariable) variable).getElement();
				final RElementName elementName= element.getElementName();
				if (elementName.getType() == RElementName.MAIN_OTHER) { // detail e.g. of promise
					return null;
				}
				lastRType= element.getRObjectType();
				segments.add(elementName);
			}
			variable= variable.getParent();
		}
		while (variable != null);
		
		if (lastRType != RObject.TYPE_ENVIRONMENT) {
			return null;
		}
		
		Collections.reverse(segments);
		
		return RElementName.create(segments);
	}
	
	private static boolean isEnv(final @Nullable RObject object) {
		return (object != null && object.getRObjectType() == RObject.TYPE_ENVIRONMENT);
	}
	
	
	private final RMainThread thread;
	
	private CombinedRElement element;
	
	private int stamp;
	
	private @Nullable IRValue value;
	
	private @Nullable CombinedRElement previousElement;
	private @Nullable IValue previousValue;
	
	
	public RElementVariable(final CombinedRElement element,
			final RMainThread thread, final int stamp,
			final @Nullable IRVariable parent) {
		super(thread.getDebugTarget(), parent);
		this.thread= thread;
		this.element= element;
		this.stamp= stamp;
	}
	
	
	public synchronized boolean update(final CombinedRElement element, final int stamp) {
		if (isValidUpdate(element)) {
			this.previousElement= this.element;
			this.previousValue= this.value;
			
			this.element= element;
			this.stamp= stamp;
			this.value= null;
			return true;
		}
		return false;
	}
	
	private boolean isValidUpdate(final CombinedRElement element) {
		if (element.getRObjectType() == this.element.getRObjectType()) {
			switch (element.getRObjectType()) {
			case RObject.TYPE_VECTOR:
				return (element.getData().getStoreType() == this.element.getData().getStoreType());
			case RObject.TYPE_ARRAY:
				return (element.getData().getStoreType() == this.element.getData().getStoreType()
						&& ((RArray<?>) element).getDim().getLength() == ((RArray<?>) this.element).getDim().getLength() );
			case RObject.TYPE_ENVIRONMENT:
			case RObject.TYPE_S4OBJECT:
				return (Objects.equals(element.getRClassName(), this.element.getRClassName()));
			default:
				return true;
			}
		}
		return false;
	}
	
	public synchronized void reset(final int stamp) {
		this.stamp= stamp;
		this.value= null;
	}
	
	
	@Override
	public final RMainThread getThread() {
		return this.thread;
	}
	
	
	public final CombinedRElement getCurrentElement() {
		return this.element;
	}
	
	public final @Nullable IRValue getCurrentValue() {
		return this.value;
	}
	
	public final int getCurrentStamp() {
		return this.stamp;
	}
	
	public final @Nullable CombinedRElement getPreviousElement() {
		return this.previousElement;
	}
	
	public final @Nullable IValue getPreviousValue() {
		return this.previousValue;
	}
	
	
	@Override
	public synchronized CombinedRElement getElement() {
		return this.element;
	}
	
	@Override
	public @Nullable RElementName getFQElementName() {
		return createFQElementName(this);
	}
	
	@Override
	public synchronized String getName() {
		return this.element.getElementName().getDisplayName();
	}
	
	@Override
	public synchronized String getReferenceTypeName() throws DebugException {
		return this.element.getRClassName();
	}
	
	@Override
	public boolean hasValueChanged() throws DebugException {
		final CombinedRElement element;
		final CombinedRElement previousElement;
		final IValue previousValue;
		synchronized (this) {
			element= this.element;
			previousElement= this.previousElement;
			previousValue= this.previousValue;
		}
		if (previousElement != null) {
			switch (element.getRObjectType()) {
			case RObject.TYPE_VECTOR:
				if (previousValue != null && element.getLength() == 1) {
					return ((RVectorValue) getValue()).hasValueChanged(0);
				}
				break;
			case RObject.TYPE_REFERENCE:
				return (((RReference) element).getHandle() != ((RReference) previousElement).getHandle());
			default:
				break;
			}
		}
		return false;
	}
	
	@Override
	public IRValue getValue() throws DebugException {
		return this.getValue(null);
	}
	
	public IRValue getValue(final @Nullable ProgressMonitor m) throws DebugException {
		CombinedRElement element;
		int stamp;
		synchronized (this) {
			if (this.value != null) {
				return this.value;
			}
			
			element= this.element;
			stamp= this.stamp;
			if (element.getRObjectType() != RObject.TYPE_REFERENCE) {
				return this.value= createValue(element);
			}
		}
		// (element.getRObjectType() == RObject.TYPE_REFERENCE)
		if (m != null) {
			try {
				element= getThread().resolveReference(element, stamp, m);
			}
			catch (final StatusException e) {
				throw new DebugException(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID,
						DebugException.TARGET_REQUEST_FAILED, "Request failed: cannot resolve reference.",
						e ));
			}
		}
		else {
			element= getThread().resolveReference(element, stamp);
		}
		IRValue value= null;
		if (element.getRObjectType() == RObject.TYPE_ENVIRONMENT) {
			value= createEnvValue((RProcessREnvironment) element, stamp);
		}
		synchronized (this) {
			if (this.value != null) {
				return this.value;
			}
			if (value == null) {
				value= createValue(element);
			}
			return this.value= value;
		}
	}
	
	@Override
	public synchronized boolean supportsValueModification() {
		switch (this.element.getRObjectType()) {
		case RObject.TYPE_VECTOR:
			return (this.element.getLength() == 1);
		default:
			return false;
		}
	}
	
	@Override
	public boolean verifyValue(final String expression) throws DebugException {
		final CombinedRElement element;
		synchronized (this) {
			element= this.element;
		}
		switch (element.getRObjectType()) {
		case RObject.TYPE_VECTOR:
			if (element.getLength() == 1) {
				return ((RVectorValue) getValue()).validateDataExpr(expression);
			}
			throw newNotSupported();
		default:
			throw newNotSupported();
		}
	}
	
	@Override
	public void setValue(final String expression) throws DebugException {
		final CombinedRElement element;
		synchronized (this) {
			element= this.element;
		}
		switch (element.getRObjectType()) {
		case RObject.TYPE_VECTOR:
			if (element.getLength() == 1) {
				((RVectorValue) getValue()).setDataExpr(0, expression);
				return;
			}
			throw newNotSupported();
		default:
			throw newNotSupported();
		}
	}
	
	
	private IRValue createValue(final CombinedRElement element) throws DebugException {
		switch (element.getRObjectType()) {
		case RObject.TYPE_VECTOR:
			return new RVectorValue(this);
		case RObject.TYPE_ARRAY:
			return new RArrayValue(this);
		case RObject.TYPE_LIST:
			return new RListValue(this);
		case RObject.TYPE_ENVIRONMENT:
			return createEnvValue((RProcessREnvironment) element, this.stamp);
		case RObject.TYPE_DATAFRAME:
		case RObject.TYPE_S4OBJECT:
			return new RListValue.ByName(this);
		case RObject.TYPE_LANGUAGE:
			return new RLanguageValue(this);
		case RObject.TYPE_FUNCTION:
			return new RFunctionValue(this);
		case RObject.TYPE_PROMISE:
			if (isEnv(element.getModelParent())) {
				return new RPromiseValue(this);
			}
			//$FALL-THROUGH$
		default:
			return new RElementVariableValue<>(this);
		}
	}
	
	private @Nullable IRValue createEnvValue(final RProcessREnvironment element, final int stamp)
			throws DebugException {
		final REnvValue envValue= this.thread.getEnvValue(element, stamp);
		if (envValue != null) {
			final RElementName elementName= element.getElementName();
			if (elementName != null && elementName.getNextSegment() == null
					&& envValue.setVariable(this)) {
				return envValue;
			}
			return RValueProxy.create(envValue, this);
		}
		throw new DebugException(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID,
				DebugException.TARGET_REQUEST_FAILED, "Request failed: reference is stale.", null));
	}
	
	
	@Override
	public int hashCode() {
		return super.hashCode();
	}
	
	@Override
	public boolean equals(@Nullable Object obj) {
		if (this == obj) {
			return true;
		}
		obj= RVariableProxy.unproxy(obj);
		return super.equals(obj);
	}
	
	@Override
	public String toString() {
		return getClass().getName() + ": " + getName(); //$NON-NLS-1$
	}
	
}
