/*=============================================================================#
 # Copyright (c) 2013, 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.r.console.core.util;

import java.util.Set;

import org.eclipse.osgi.util.NLS;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImSet;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.ts.core.SystemRunnable;
import org.eclipse.statet.jcommons.ts.core.Tool;

import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.r.console.core.RProcessREnvironment;
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.ICombinedRDataAdapter;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.ts.core.RToolService;


public class LoadReferenceRunnable extends AbstractStatetRRunnable implements SystemRunnable {
	
	
	public static RProcess findRProcess(CombinedRElement element) {
		while (element != null) {
			if (element instanceof RProcessREnvironment) {
				return ((RProcessREnvironment) element).getSource();
			}
			element= element.getModelParent();
		}
		return null;
	}
	
	
	private static final ImSet<String> LOAD_PKG_EXCLUDE_LIST= ImCollections.newSet(
			System.getProperty("org.eclipse.statet.r.console.namespaces.load.exclude", "") //$NON-NLS-1$ //$NON-NLS-2$
					.split(",") ); //$NON-NLS-1$
	
	public static boolean isAccessAllowed(final RElementName name, final RWorkspace rWorkspace) {
		final Set<String> excludePkgs= LOAD_PKG_EXCLUDE_LIST;
		if (excludePkgs.isEmpty()) {
			return true;
		}
		
		final String pkgName;
		if (RElementName.isPackageFacetScopeType(name.getType())) {
			pkgName= name.getSegmentName();
		}
		else if (name.getScope() != null
				&& RElementName.isPackageFacetScopeType(name.getScope().getType()) ) {
			pkgName= name.getScope().getSegmentName();
		}
		else {
			return true;
		}
		
		return (!(excludePkgs.contains("*") || excludePkgs.contains(pkgName)) //$NON-NLS-1$
				|| rWorkspace.isNamespaceLoaded(pkgName) );
	}
	
	
	private final RReference reference;
	private final RElementName name;
	
	private final RProcess process;
	
	private final int stamp;
	private int loadOptions;
	
	private CombinedRElement resolvedElement;
	
	private boolean cancel;
	private int state;
	
	private Runnable finishRunnable;
	
	
	public LoadReferenceRunnable(final RReference reference, final RProcess tool,
			final int stamp, final String cause) {
		super("r/workspace/loadElements", //$NON-NLS-1$
				NLS.bind("Load elements of {0} (requested for {1})", 
						((CombinedRElement) reference).getElementName().getDisplayName(),
						cause ));
		
		this.reference= reference;
		this.name= null;
		
		this.process= tool;
		this.stamp= stamp;
	}
	
	public LoadReferenceRunnable(final RElementName name, final RProcess tool,
			final int stamp, final String cause) {
		super("r/workspace/loadElements", //$NON-NLS-1$
				NLS.bind("Load elements of {0} (requested for {1})", 
						name.getDisplayName(),
						cause ));
		
		this.reference= null;
		this.name= name;
		
		this.process= tool;
		this.stamp= stamp;
	}
	
	
	public final RProcess getTool() {
		return this.process;
	}
	
	public int getLoadOptions() {
		return this.loadOptions;
	}
	
	public void setLoadOptions(final int options) {
		this.loadOptions= options;
	}
	
	public int getRequiredStamp() {
		return this.stamp;
	}
	
	
	public void cancel() {
		this.cancel= true;
	}
	
	public CombinedRElement getResolvedElement() {
		return this.resolvedElement;
	}
	
	
	public boolean isStarted() {
		return (this.state == STARTING);
	}
	
	public boolean isFinished() {
		return ((this.state & MASK_EVENT_GROUP) == FINISHING_EVENT_GROUP);
	}
	
	public void setFinishRunnable(final Runnable runnable) {
		this.finishRunnable= runnable;
	}
	
	
	@Override
	public boolean canRunIn(final Tool tool) {
		return (tool == this.process);
	}
	
	@Override
	public boolean changed(final int event, final Tool tool) {
		Runnable runnable= null;
		switch (event) {
		case REMOVING_FROM:
			if (this.cancel) {
				synchronized (this) {
					this.state= event;
					LoadReferenceRunnable.this.notifyAll();
					return true;
				}
			}
			return false;
		case MOVING_FROM:
			return false;
		case BEING_ABANDONED:
		case FINISHING_OK:
		case FINISHING_ERROR:
		case FINISHING_CANCEL:
			synchronized (this) {
				this.state= event;
				runnable= this.finishRunnable;
				LoadReferenceRunnable.this.notifyAll();
			}
			break;
		default:
			break;
		}
		
		if (runnable != null) {
			runnable.run();
		}
		
		return true;
	}
	
	@Override
	public void run(final RToolService service,
			final ProgressMonitor m) throws StatusException {
		final ICombinedRDataAdapter r= (ICombinedRDataAdapter) service;
		if (this.stamp != 0 && this.stamp != r.getChangeStamp()) {
			return;
		}
		final int loadOptions;
		synchronized (this) {
			this.state= STARTING;
			loadOptions= this.loadOptions;
		}
		final RWorkspace workspace= r.getWorkspaceData();
		if (this.reference != null) {
			this.resolvedElement= workspace.resolve(this.reference, RWorkspace.RESOLVE_UPTODATE,
					loadOptions, m );
		}
		else {
			this.resolvedElement= workspace.resolve(this.name, RWorkspace.RESOLVE_UPTODATE,
					loadOptions, m );
		}
	}
	
}
