/*=============================================================================#
 # Copyright (c) 2016, 2018 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.eval;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;

import org.eclipse.statet.jcommons.collections.ImCollections;
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.lang.ObjectUtils;
import org.eclipse.statet.jcommons.lang.ObjectUtils.ToStringBuilder;

import org.eclipse.statet.ecommons.debug.core.eval.IEvaluationListener;
import org.eclipse.statet.ecommons.ts.core.SystemRunnable;
import org.eclipse.statet.ecommons.ts.core.Tool;

import org.eclipse.statet.internal.r.debug.core.Messages;
import org.eclipse.statet.internal.r.debug.core.RDebugCorePlugin;
import org.eclipse.statet.internal.r.debug.core.RJTmp;
import org.eclipse.statet.internal.r.debug.core.model.RElementVariable;
import org.eclipse.statet.internal.r.debug.core.model.RMainThread;
import org.eclipse.statet.r.console.core.RWorkspace;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.tool.AbstractStatetRRunnable;
import org.eclipse.statet.r.nico.AbstractRDbgController;
import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
import org.eclipse.statet.rj.data.impl.RReferenceImpl;
import org.eclipse.statet.rj.eclient.core.RToolService;
import org.eclipse.statet.rj.services.FunctionCall;
import org.eclipse.statet.rj.services.RService;


@NonNullByDefault
public class EvalExpressionRunnable extends AbstractStatetRRunnable implements SystemRunnable {
	
	
	private final REvalExpressionTask task;
	
	private final int stamp;
	
	private final IEvaluationListener listener;
	
	private int state;
	
	
	public EvalExpressionRunnable(final REvalExpressionTask task, final int stamp,
			final IEvaluationListener listener) {
		super("r/dbg/watch", Messages.Expression_Evaluate_task);
		
		this.task= task;
		this.stamp= stamp;
		this.listener= listener;
	}
	
	
	@Override
	public boolean canRunIn(final Tool tool) {
		return (tool == this.task.getThread().getTool());
	}
	
	@Override
	public boolean changed(final int event, final Tool tool) {
		switch (event) {
		case REMOVING_FROM:
		case MOVING_FROM:
			return false;
		case BEING_ABANDONED:
		case FINISHING_OK:
		case FINISHING_ERROR:
		case FINISHING_CANCEL:
			synchronized (this) {
				if (this.state == 0) {
					this.state= event;
					this.listener.evaluationFinished(new REvaluationResult(
							this.task.getRExpression(), this.task.getThread()) );
				}
			}
			break;
		default:
			break;
		}
		
		return true;
	}
	
	@Override
	protected void run(final RToolService service,
			final IProgressMonitor monitor) throws CoreException {
		try {
			final AbstractRDbgController r= (AbstractRDbgController) service;
			
			if (this.stamp != r.getChangeStamp()) {
				return;
			}
			
			final RMainThread thread= this.task.getThread();
			final @Nullable REvaluationResult result= thread.getExpressionManager()
					.getEvalResult(this.task.getKey());
			if (result != null) {
				this.state= FINISHING_OK;
				this.listener.evaluationFinished(result);
				return;
			}
			
			final @NonNull String id;
			{	final FunctionCall call= r.createFunctionCall(RJTmp.CREATE_ID);
				call.addChar(RJTmp.PREFIX_PAR, "dbg_watch"); //$NON-NLS-1$
				id= RDataUtils.checkSingleCharValue(call.evalData(monitor));
			}
			try {
				evalExpression(id, r, monitor);
			}
			finally {
				if (this.state != FINISHING_OK) {
					thread.getExpressionManager().cleanEvalResult(id, r, monitor);
				}
			}
		}
		catch (final CoreException | UnexpectedRDataException e) {
			this.state= FINISHING_ERROR;
			final ToStringBuilder sb= new ObjectUtils.ToStringBuilder(
					"An error occurred when evaluating watch expression." );
			sb.addProp("expression", this.task.getRExpression()); //$NON-NLS-1$
			sb.addProp("frame", this.task.getStackFrame()); //$NON-NLS-1$
			RDebugCorePlugin.log(new Status(IStatus.ERROR, RDebugCorePlugin.BUNDLE_ID, 0,
					sb.toString(), e ));
		}
	}
	
	private void evalExpression(final String id, final AbstractRDbgController r,
			final IProgressMonitor monitor) throws UnexpectedRDataException, CoreException, DebugException {
		final RMainThread thread= this.task.getThread();
		
		final String valueName= id + ".value"; //$NON-NLS-1$
		final RElementName valueElementName= RElementName.create(ImCollections.newList(
				RJTmp.PKG_NAME, RJTmp.ENV_NAME,
				RElementName.create(RElementName.MAIN_DEFAULT, valueName) ));
		
//		System.out.println(this.task.getRExpression() + " in " + this.task.getStackFrame());
		
		CombinedRElement element;
		final RReference ref;
		try {
			element= r.evalCombinedStruct(
					this.task.getRExpression(),
					new RReferenceImpl(this.task.getStackFrame().getHandle(), RObject.TYPE_ENVIRONMENT, null),
					0, RService.DEPTH_REFERENCE, valueElementName, monitor );
			ref= RDataUtils.checkRReference(element);
		}
		catch (final CoreException e) {
			synchronized (this) {
				this.state= FINISHING_ERROR;
				final IStatus status= e.getStatus();
				if (status.getSeverity() == IStatus.CANCEL) {
					evalCompleted(new REvaluationResult(this.task.getRExpression(), thread,
							IStatus.CANCEL, Messages.Expression_Evaluate_Cancelled_message ));
				}
				else {
					evalCompleted(new REvaluationResult(this.task.getRExpression(), thread,
							IStatus.ERROR, status.getMessage() ));
				}
				return;
			}
		}
		
		{	final FunctionCall call= r.createFunctionCall(RJTmp.SET);
			call.addChar(RJTmp.NAME_PAR, valueName);
			call.add(RJTmp.VALUE_PAR, ref);
			call.evalVoid(monitor);
		}
		
		if (ref.getReferencedRObjectType() == RObject.TYPE_ENVIRONMENT) {
			thread.resolveReference((CombinedRElement) ref, this.stamp, monitor);
		}
		else {
			element= r.getWorkspaceData().resolve(ref, RWorkspace.RESOLVE_UPTODATE, 0, monitor);
			if (element == null) {
				element= r.evalCombinedStruct(valueElementName, 0, RService.DEPTH_INFINITE,
						monitor );
				if (element == null) {
					throw new UnexpectedRDataException("null");
				}
			}
		}
		
		final RElementVariable variable= new RElementVariable(element, thread, this.stamp, null);
		variable.getValue(monitor);
		this.state= FINISHING_OK;
		evalCompleted(new REvaluationResult(this.task.getRExpression(), thread,
				variable, id ));
	}
	
	private void evalCompleted(final REvaluationResult evalResult) {
		this.task.getThread().getExpressionManager().setEvalResult(this.task.getKey(), evalResult);
		this.listener.evaluationFinished(evalResult);
	}
	
}
