/*=============================================================================#
 # Copyright (c) 2008, 2017 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.redocs.tex.r.ui.processing;

import static org.eclipse.statet.docmlet.base.ui.processing.DocProcessingOperation.NO_SETTINGS;
import static org.eclipse.statet.docmlet.base.ui.processing.DocProcessingToolConfig.StepConfig.RUN_DEFAULT;
import static org.eclipse.statet.docmlet.base.ui.processing.DocProcessingToolConfig.StepConfig.RUN_EXPLICITE;
import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.BUILDTEX_TYPE_ECLIPSE;
import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.BUILDTEX_TYPE_RCONSOLE;
import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.SWEAVE_TYPE_RCMD;
import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.SWEAVE_TYPE_RCONSOLE;
import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.VARNAME_LATEX_FILE;
import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.VARNAME_OUTPUT_FILE;
import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.VARNAME_SWEAVE_FILE;

import java.util.concurrent.Callable;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.osgi.util.NLS;
import org.eclipse.texlipse.TexPathConfig;
import org.eclipse.texlipse.Texlipse;
import org.eclipse.texlipse.builder.AbstractBuilder;
import org.eclipse.texlipse.builder.Builder;
import org.eclipse.texlipse.builder.TexlipseBuilder;
import org.eclipse.texlipse.viewer.ViewerConfiguration;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;

import org.eclipse.statet.ecommons.debug.core.util.LaunchUtils;
import org.eclipse.statet.ecommons.io.FileUtil;
import org.eclipse.statet.ecommons.io.FileValidator;
import org.eclipse.statet.ecommons.ts.core.Tool;
import org.eclipse.statet.ecommons.ts.core.ToolRunnable;
import org.eclipse.statet.ecommons.ts.core.ToolService;
import org.eclipse.statet.ecommons.variables.core.VariableText;
import org.eclipse.statet.ecommons.variables.core.VariableText.LocationProcessor;

import org.eclipse.statet.docmlet.base.ui.processing.DocProcessingToolProcess;
import org.eclipse.statet.docmlet.base.ui.processing.operations.OpenUsingEclipseOperation;
import org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.Config;
import org.eclipse.statet.nico.core.runtime.IRequireSynch;
import org.eclipse.statet.nico.core.runtime.ToolProcess;
import org.eclipse.statet.nico.core.runtime.ToolWorkspace;
import org.eclipse.statet.nico.ui.NicoUI;
import org.eclipse.statet.nico.ui.NicoUITools;
import org.eclipse.statet.r.console.core.IRBasicAdapter;
import org.eclipse.statet.r.console.core.RConsoleTool;
import org.eclipse.statet.r.core.RUtil;
import org.eclipse.statet.redocs.tex.r.ui.TexRweaveUI;
import org.eclipse.statet.rj.services.RServiceControlExtension;


class TexRweaveProcessToolProcess extends DocProcessingToolProcess {
	
	
	private static final int TICKS_PREPARER= 5;
	private static final int TICKS_RWEAVE= 30;
	private static final int TICKS_TEX= 30;
	private static final int TICKS_OPEN_TEX= 5;
	private static final int TICKS_OPEN_OUTPUT= 20;
	private static final int TICKS_REST= 10;
	
	
	public static final ImList<String> SWEAVE_FOLDER_VARNAMES= ImCollections.newList(
			VARNAME_SWEAVE_FILE );
	public static final ImList<String> SWEAVE_COMMAND_VARNAMES= ImCollections.newList(
			VARNAME_SWEAVE_FILE, VARNAME_LATEX_FILE, VARNAME_OUTPUT_FILE );
	public static final ImList<String> OUTPUT_DIR_VARNAMES= ImCollections.newList(
			VARNAME_SWEAVE_FILE, VARNAME_LATEX_FILE );
	public static final ImList<String> TEX_COMMAND_VARNAMES= ImCollections.newList(
			VARNAME_SWEAVE_FILE, VARNAME_LATEX_FILE, VARNAME_OUTPUT_FILE );
	
	
	private class R implements ToolRunnable {
		
		
		public static final int TASK_FINISHED= 1;
		public static final int TASK_PREPARE_TEX= 2;
		
		private int task= 0;
		
		
		R() {
		}
		
		@Override
		public String getTypeId() {
			return "r/sweave/commands"; //$NON-NLS-1$
		}
		
		@Override
		public boolean canRunIn(final Tool tool) {
			return (tool.isProvidingFeatureSet(RConsoleTool.R_BASIC_FEATURESET_ID));
		}
		
		@Override
		public String getLabel() {
			return NLS.bind(Messages.RweaveTexProcessing_Sweave_Task_label, getConfig().getSourceFile().getName());
		}
		
		@Override
		public boolean changed(final int event, final Tool tool) {
			switch (event) {
			case REMOVING_FROM:
			case BEING_ABANDONED:
				getStatus().add(new Status(IStatus.CANCEL, TexRweaveUI.BUNDLE_ID, -1,
						Messages.RweaveTexProcessing_Sweave_Task_info_Canceled_message, null));
				continueAfterR();
				break;
			// finishing handled in run
			}
			return true;
		}
		
		@Override
		public void run(final ToolService service,
				final IProgressMonitor monitor) throws CoreException {
			final IRBasicAdapter r= (IRBasicAdapter) service;
			TexRweaveProcessToolProcess.this.fProgress2= monitor;
			Callable<Boolean> cancel= null;
			if (r instanceof RServiceControlExtension) {
				cancel= new Callable<Boolean>() {
					@Override
					public Boolean call() throws Exception {
						terminate();
						return Boolean.FALSE;
					}
				};
				((RServiceControlExtension) r).addCancelHandler(cancel);
			}
			try {
				if (checkExit(0)) {
					return;
				}
				
				final ToolWorkspace workspace= r.getWorkspaceData();
				if (TexRweaveProcessToolProcess.this.fWorkingFolder == null) {
					r.refreshWorkspaceData(0, monitor);
					updatePathInformations(r.getWorkspaceData());
				}
				else {
					String path= workspace.toToolPath(TexRweaveProcessToolProcess.this.fWorkingFolder);
					path= RUtil.escapeBackslash(path);
					r.submitToConsole("setwd(\""+path+"\")", monitor); //$NON-NLS-1$ //$NON-NLS-2$
					r.refreshWorkspaceData(0, monitor);
					if (!TexRweaveProcessToolProcess.this.fWorkingFolder.equals(workspace.getWorkspaceDir())) {
						getStatus().add(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID,
								"Failed to set the R working directory." ));
					}
				}
				
				if (checkExit(0)) {
					return;
				}
				
				final LocationProcessor processor= new LocationProcessor() {
					@Override
					public String process(String path) throws CoreException {
						final IFileStore store= FileUtil.getFileStore(path);
						path= workspace.toToolPath(store);
						path= RUtil.escapeBackslash(path);
						return path;
					}
				};
				
				if (getConfig().weave.isRun() && TexRweaveProcessToolProcess.this.fSweaveType == SWEAVE_TYPE_RCONSOLE) {
					monitor.subTask("Sweave"); //$NON-NLS-1$
					final SubMonitor progress= TexRweaveProcessToolProcess.this.fProgress.newChild(TICKS_RWEAVE);
					progress.beginTask(Messages.RweaveTexProcessing_Sweave_InConsole_label, 100);
					
					try {
						TexRweaveProcessToolProcess.this.fSweaveRCommands.set(VARNAME_SWEAVE_FILE, getConfig().getSourceFile().getFullPath().toString());
						TexRweaveProcessToolProcess.this.fSweaveRCommands.set(VARNAME_LATEX_FILE, TexRweaveProcessToolProcess.this.fTexFile.getFullPath().toString());
						TexRweaveProcessToolProcess.this.fSweaveRCommands.set(VARNAME_OUTPUT_FILE, TexRweaveProcessToolProcess.this.fTexPathConfig.getOutputFile().getFullPath().toString());
						TexRweaveProcessToolProcess.this.fSweaveRCommands.performFinalStringSubstitution(processor);
					}
					catch (final NullPointerException e) {
						throw new CoreException(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID,
								Messages.RweaveTexProcessing_Sweave_error_ResourceVariable_message));
					}
					catch (final CoreException e) {
						throw new CoreException(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID,
								Messages.RweaveTexProcessing_Sweave_error_ResourceVariable_message + ' ' + e.getLocalizedMessage()));
					}
					final String[] commands= RUtil.LINE_SEPARATOR_PATTERN.split(TexRweaveProcessToolProcess.this.fSweaveRCommands.getText());
					for (int i= 0; i < commands.length; i++) {
						r.submitToConsole(commands[i], monitor);
					}
					if (r instanceof IRequireSynch) {
						((IRequireSynch) r).synch(monitor);
					}
				}
				
				if (getConfig().produce.isRun() && TexRweaveProcessToolProcess.this.fTexType == BUILDTEX_TYPE_RCONSOLE) {
					monitor.subTask("LaTeX"); //$NON-NLS-1$
					if (checkExit(0)) {
						return;
					}
					
					waitTask(TASK_PREPARE_TEX);
					if (checkExit(0) || this.task < 0) {
						return;
					}
					
					final SubMonitor progress= TexRweaveProcessToolProcess.this.fProgress.newChild(TICKS_TEX);
					progress.beginTask(Messages.RweaveTexProcessing_Tex_label, 100);
					
					try {
						TexRweaveProcessToolProcess.this.fTexRCommands.set(VARNAME_SWEAVE_FILE, getConfig().getSourceFile().getFullPath().toString());
						TexRweaveProcessToolProcess.this.fTexRCommands.set(VARNAME_LATEX_FILE, TexRweaveProcessToolProcess.this.fTexFile.getFullPath().toString());
						TexRweaveProcessToolProcess.this.fTexRCommands.set(VARNAME_OUTPUT_FILE, TexRweaveProcessToolProcess.this.fTexPathConfig.getOutputFile().getFullPath().toString());
						TexRweaveProcessToolProcess.this.fTexRCommands.performFinalStringSubstitution(processor);
						progress.setWorkRemaining(90);
					}
					catch (final NullPointerException e) {
						throw new CoreException(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID,
								Messages.RweaveTexProcessing_Tex_error_ResourceVariable_message));
					}
					catch (final CoreException e) {
						throw new CoreException(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID,
								Messages.RweaveTexProcessing_Tex_error_ResourceVariable_message + ' ' + e.getLocalizedMessage()));
					}
					
					Texlipse.getViewerManager().closeDocInViewer(TexRweaveProcessToolProcess.this.fTexPathConfig);
					
					final String[] commands= RUtil.LINE_SEPARATOR_PATTERN.split(TexRweaveProcessToolProcess.this.fTexRCommands.getText());
					for (int i= 0; i < commands.length; i++) {
						r.submitToConsole(commands[i], monitor);
						progress.setWorkRemaining(90-80/commands.length*(i+1));
					}
					if (r instanceof IRequireSynch) {
						((IRequireSynch) r).synch(monitor);
					}
				}
			}
			catch (final CoreException e) {
				getStatus().add(e.getStatus());
				throw e;
			}
			finally {
				if (cancel != null) {
					((RServiceControlExtension) r).removeCancelHandler(cancel);
					cancel= null;
				}
				continueAfterR();
				TexRweaveProcessToolProcess.this.fProgress2= null;
			}
			
		}
		
		private void updatePathInformations(final ToolWorkspace workspace) {
			final IFileStore wd= workspace.getWorkspaceDir();
			final IStatus status= setWorkingDir(wd, null, true);
			if (status.getSeverity() > IStatus.OK) {
				getStatus().add(status);
			}
		}
		
		private synchronized void waitTask(final int task) {
			this.task= task;
			while (this.task == task) {
				notifyAll();
				try {
					this.wait();
				}
				catch (final InterruptedException e) {
				}
			}
		}
		
		private synchronized void continueAfterR() {
			this.task= TASK_FINISHED;
			notifyAll();
		}
		
	}
	
	private SubMonitor fProgress;
	private IProgressMonitor fProgress2;
	
	private IContainer fWorkingFolderInWorkspace;
	private IFileStore fWorkingFolder;
	private String fBaseFileName;
	private String fTexFileExtension;
	
	private int fSweaveType;
	private VariableText fSweaveRCommands;
	private ILaunchConfiguration fSweaveConfig;
	
	private String fOutputFormat;
	private VariableText fOutputDir;
	private boolean fOutputInitialized;
	
	private IFile fTexFile;
	int fTexOpenEditor= 0;
	private int fTexType;
	private Builder fTexBuilder;
	private VariableText fTexRCommands;
	private TexPathConfig fTexPathConfig;
	
	ViewerConfiguration fPreviewConfig;
	
	
	public TexRweaveProcessToolProcess(final ILaunch launch, final TexRweaveLaunchDelegate.Config config) {
		super(launch, config);
	}
	
	
	@Override
	public TexRweaveLaunchDelegate.Config getConfig() {
		return (TexRweaveLaunchDelegate.Config) super.getConfig();
	}
	
	public void setWorkingDir(final VariableText wd) throws CoreException {
		wd.performInitialStringSubstitution(true);
		wd.set(VARNAME_SWEAVE_FILE, getConfig().getSourceFile().getFullPath().toString());
		wd.performFinalStringSubstitution(null);
		
		final FileValidator validator= new FileValidator(false);
		validator.setResourceLabel("Sweave Working / Output Folder");
		validator.setOnFile(IStatus.ERROR);
		validator.setOnExisting(IStatus.OK);
		validator.setOnNotExisting(IStatus.ERROR);
		validator.setRequireWorkspace(true, true);
		{	final IStatus status= validator.validate(wd.getText());
			if (!status.isOK()) {
				throw new CoreException(status);
			}
		}
		{	final IStatus status= setWorkingDir(null, (IContainer) validator.getWorkspaceResource(), true);
			if (!status.isOK()) {
				throw new CoreException(status);
			}
		}
	}
	
	public void setSweave(final VariableText rCommands) throws CoreException {
		if (this.fSweaveType > 0 || rCommands == null) {
			throw new IllegalArgumentException();
		}
		this.fSweaveType= SWEAVE_TYPE_RCONSOLE;
		this.fSweaveRCommands= rCommands;
		this.fSweaveRCommands.performInitialStringSubstitution(true);
	}
	
	public void setSweave(final ILaunchConfiguration rCmd) {
		if (this.fSweaveType > 0 || rCmd == null) {
			throw new IllegalArgumentException();
		}
		this.fSweaveType= SWEAVE_TYPE_RCMD;
		this.fSweaveConfig= rCmd;
	}
	
	public void setOutput(final VariableText directory, final String format) throws CoreException {
		this.fOutputDir= directory;
		this.fOutputDir.performInitialStringSubstitution(true);
		this.fOutputFormat= format;
		
		if (this.fWorkingFolder != null && !this.fOutputInitialized) {
			final IStatus status= initOutputDir();
			if (!status.isOK()) {
				throw new CoreException(status);
			}
		}
	}
	
	public void setBuildTex(final VariableText commands) throws CoreException {
		if (this.fTexType > 0 || commands == null) {
			throw new IllegalArgumentException();
		}
		this.fTexType= BUILDTEX_TYPE_RCONSOLE;
		this.fTexRCommands= commands;
		this.fTexRCommands.performInitialStringSubstitution(true);
	}
	
	public void setBuildTex(final Builder texBuilder) {
		if (this.fTexType > 0 || texBuilder == null) {
			throw new IllegalArgumentException();
		}
		this.fTexType= BUILDTEX_TYPE_ECLIPSE;
		this.fTexBuilder= texBuilder;
	}
	
	
	public IStatus setWorkingDir(final IFileStore efsFolder, final IContainer workspaceFolder, final boolean synch) {
		this.fWorkingFolder= efsFolder;
		this.fWorkingFolderInWorkspace= workspaceFolder;
		if (synch) {
			if (this.fWorkingFolder == null && this.fWorkingFolderInWorkspace != null) {
				this.fWorkingFolder= EFS.getLocalFileSystem().getStore(this.fWorkingFolderInWorkspace.getLocation());
			}
			else if (this.fWorkingFolder != null && this.fWorkingFolderInWorkspace == null) {
				final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
				final IContainer[] found= root.findContainersForLocationURI(this.fWorkingFolder.toURI());
				for (int i= 0; i < found.length; i++) {
					if (found[i].getType() == IResource.PROJECT || found[i].getType() == IResource.FOLDER) {
						this.fWorkingFolderInWorkspace= found[i];
						break;
					}
				}
			}
		}
		if (this.fWorkingFolderInWorkspace == null) {
			doSetExitValue(11);
			return new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, -1,
					Messages.RweaveTexProcessing_Tex_error_MustBeInWorkspace_message, null);
		}
		
		if (this.fBaseFileName == null) {
			this.fBaseFileName= getConfig().getSourceFile().getName();
			final int idx= this.fBaseFileName.lastIndexOf('.');
			if (idx >= 0) {
				this.fBaseFileName= this.fBaseFileName.substring(0, idx);
			}
		}
			
		if (this.fTexFileExtension == null) {
			this.fTexFileExtension= "tex";  //$NON-NLS-1$
		}
		this.fTexFile= this.fWorkingFolderInWorkspace.getFile(new Path(this.fBaseFileName + '.' + this.fTexFileExtension));
		
		if (this.fOutputDir != null && !this.fOutputInitialized) {
			return initOutputDir();
		}
		return Status.OK_STATUS;
	}
	
	private IStatus initOutputDir() {
		this.fOutputInitialized= true;
		final String texFilePath= this.fTexFile.getFullPath().toString();
		this.fOutputDir.set(VARNAME_SWEAVE_FILE, getConfig().getSourceFile().getFullPath().toString());
		this.fOutputDir.set(VARNAME_LATEX_FILE, texFilePath);
		
		// 21x
		if (this.fOutputFormat == null) {
			return new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, -1,
					Messages.RweaveTexProcessing_Tex_error_BuilderNotConfigured_message, null );
		}
		final IContainer outputDir;
		try {
			outputDir= TexPathConfig.resolveDirectory(this.fOutputDir.getText(), this.fTexFile, getConfig().getSourceFile());
		}
		catch (final CoreException e) {
			return new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, -1,
					Messages.RweaveTexProcessing_Tex_error_OutputDir_message, e );
		}
		this.fTexPathConfig= new TexPathConfig(this.fTexFile, outputDir, this.fOutputFormat);
		
		return Status.OK_STATUS;
	}
	
	public IFileStore getWorkingDirectory() {
		return this.fWorkingFolder;
	}
	
	
	@Override
	protected void runProcessing(final SubMonitor m) {
		this.fProgress= m;
		
		if (checkExit(0)) {
			return;
		}
		
		doWeave();
		if (checkExit(0)) {
			return;
		}
		
		if (!this.fOutputInitialized) {
			final IStatus status= initOutputDir();
			if (!status.isOK()) {
				getStatus().add(status);
			}
		}
		if (checkExit(0)) {
			return;
		}
		
		if (getConfig().produce.isRun() && this.fTexType == BUILDTEX_TYPE_RCONSOLE) {
			finallyTex(this.fProgress.newChild(1));
		}
		else {
			doPrepareTex();
			if (checkExit(0)) {
				return;
			}
			
			doProcessTex();
			if (checkExit(0)) {
				return;
			}
		}
		
		doOpenOutput();
		
		this.fProgress.done();
	}
	
	@Override
	protected int calculateTicks() {
		final Config config= getConfig();
		int sum= 0;
		if (config.weave.isRun()) {
			sum += TICKS_RWEAVE;
		}
		else {
			sum += TICKS_RWEAVE/10;
		}
		if (this.fTexOpenEditor >= TexTab.OPEN_ALWAYS) {
			sum += TICKS_OPEN_TEX;
		}
		if (config.produce.isRun()) {
			sum += TICKS_TEX;
		}
		if (config.preview.isRun()) {
			sum += TICKS_OPEN_OUTPUT;
		}
		sum += TICKS_REST;
		
		return sum;
	}
	
	
	@Override
	protected void runFinished() {
		super.runFinished();
		
		this.fProgress= null;
		
		if (getStatus().getSeverity() > IStatus.OK) {
			if (getStatus().getSeverity() == IStatus.ERROR) {
				StatusManager.getManager().handle(getStatus(), StatusManager.LOG | StatusManager.SHOW);
				return;
			}
			StatusManager.getManager().handle(getStatus(), StatusManager.LOG);
		}
	}
	
	
	private void doWeave() { // 1xx
		final Config config= getConfig();
		if (this.fSweaveType == SWEAVE_TYPE_RCONSOLE || this.fTexType == BUILDTEX_TYPE_RCONSOLE) { // 11x
			if (!(config.weave.isRun() || config.produce.isRun()) && this.fWorkingFolder != null) {
				return;
			}
			try {
	//			RCodeLaunchRegistry.runRCodeDirect(RUtil.LINE_SEPARATOR_PATTERN.split(fSweaveCommands), false);
				final ToolProcess rProcess= NicoUI.getToolRegistry().getActiveToolSession(
						getConfig().getWorkbenchPage() ).getProcess();
				if (rProcess == null) {
					NicoUITools.accessTool(RConsoleTool.TYPE, rProcess); // throws CoreException
				}
				
				final R rTask= new R();
				if (config.weave.isRun() || config.produce.isRun()) {
					this.fProgress.worked(TICKS_PREPARER);
					
					final IStatus submitStatus= rProcess.getQueue().add(rTask);
					if (submitStatus.getSeverity() > IStatus.OK) {
						getStatus().add(submitStatus);
						if (checkExit(112)) {
							return;
						}
					}
					RTASK: while (true) {
						synchronized (rTask) {
							boolean ok= false;
							try {
								rTask.notifyAll();
								if (rTask.task != R.TASK_FINISHED && checkExit(0)) {
									rTask.task= -1;
									// removing runnable sets the cancel status
									rProcess.getQueue().remove(rTask);
								}
								switch (rTask.task) {
								case R.TASK_FINISHED:
									ok= true;
									break RTASK;
								case R.TASK_PREPARE_TEX:
									doPrepareTex();
									ok= true;
									rTask.task= 0;
									break;
								default:
									ok= true;
								}
								rTask.wait(100);
							}
							catch (final InterruptedException e) {
								// continue loop, monitor is checked
							}
							finally {
								if (!ok) {
									rTask.task= -1;
								}
							}
						}
					}
					if (checkExit(113)) {
						return;
					}
				}
				else if (this.fWorkingFolder == null) { // we need the working directory
					final SubMonitor m= this.fProgress.newChild(TICKS_RWEAVE/10);
					rTask.updatePathInformations(rProcess.getWorkspaceData());
					m.done();
				}
			}
			catch (final CoreException e) {
				abort(e, 110);
				return;
			}
		}
		else if (this.fSweaveConfig != null) { // 12x
			if (!config.weave.isRun() && this.fWorkingFolder != null) {
				return;
			}
			try {
				if (config.weave.isRun()) {
					final SubMonitor monitor= this.fProgress.newChild(TICKS_RWEAVE);
					monitor.beginTask(Messages.RweaveTexProcessing_Sweave_RCmd_label, 100);
					final ILaunchConfigurationDelegate delegate= LaunchUtils.getLaunchConfigurationDelegate(
							this.fSweaveConfig, ILaunchManager.RUN_MODE, getStatus() );
					delegate.launch(this.fSweaveConfig, ILaunchManager.RUN_MODE, getLaunch(), monitor.newChild(75));
					final IProcess[] processes= getLaunch().getProcesses();
					if (processes.length == 0) {
						throw new IllegalStateException();
					}
					final IProcess sweaveProcess= processes[processes.length-1];
					if (!sweaveProcess.isTerminated()) {
						throw new IllegalStateException();
					}
					final int exitValue= sweaveProcess.getExitValue();
					if (exitValue != 0) {
						abort(IStatus.CANCEL, NLS.bind(Messages.RweaveTexProcessing_Sweave_RCmd_error_Found_message, exitValue), null,
								121);
						return;
					}
					monitor.done();
				}
			}
			catch (final CoreException e) {
				abort(e, 120);
				return;
			}
		}
	}
	
	private void doPrepareTex() {
		final Config config= getConfig();
		final ISchedulingRule rule= beginSchedulingRule(this.fTexFile.getParent(), this.fProgress.newChild(1));
		try {
			if ((config.weave.isRun() || config.produce.isRun()) && this.fTexFile.exists() && this.fTexFile.getType() == IResource.FILE) {
				try {
					this.fTexFile.deleteMarkers(TexlipseBuilder.MARKER_TYPE, true, IResource.DEPTH_INFINITE);
					this.fTexFile.deleteMarkers(TexlipseBuilder.LAYOUT_WARNING_TYPE, true, IResource.DEPTH_INFINITE);
				}
				catch (final CoreException e) {}
			}
			this.fProgress.worked(1);
			refreshDir(this.fTexFile, this.fProgress.newChild(1));
			if (checkExit(195)) {
				return;
			}
			
			final boolean exists= this.fTexFile.exists() && this.fTexFile.getType() == IResource.FILE;
			if (config.produce.isRun() && !exists) {
				doSetExitValue(199);
				getStatus().add(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, -1,
						NLS.bind(Messages.RweaveTexProcessing_Tex_error_NotFound_message, this.fTexFile.getFullPath().toString()), null));
				return;
			}
			
			if ((config.weave.isRun() || getConfig().produce.isRun()) && exists && this.fTexOpenEditor == TexTab.OPEN_ALWAYS) {
				final OpenUsingEclipseOperation operation= new OpenUsingEclipseOperation(this.fTexFile);
				try {
					operation.init(config.produce, NO_SETTINGS, this.fProgress.newChild(1));
					operation.setFailSeverity(IStatus.WARNING);
					operation.run(this, this.fProgress.newChild(TICKS_OPEN_TEX - 1));
				}
				catch (final CoreException e) {}
			}
		}
		finally {
			endSchedulingRule(rule);
		}
	}
	
	private void doProcessTex() { // 2xx
		if (getConfig().produce.isRun() && this.fTexType == TexRweaveLaunchDelegate.BUILDTEX_TYPE_ECLIPSE) {
			final SubMonitor m1= this.fProgress.newChild(TICKS_TEX);
			this.fProgress.beginTask(Messages.RweaveTexProcessing_Tex_label, 100);
			Texlipse.getViewerManager().closeDocInViewer(this.fTexPathConfig);
			try {
				this.fTexBuilder.reset(m1.newChild(60, SubMonitor.SUPPRESS_SUBTASK));
				this.fTexBuilder.build(this.fTexPathConfig);
				AbstractBuilder.checkOutput(this.fTexPathConfig, m1.newChild(10));
			}
			catch (final OperationCanceledException e) {
				abort(IStatus.CANCEL, Messages.RweaveTexProcessing_info_Canceled_message, e,
						211);
				return;
			}
			catch (final CoreException e) {
				abort(e, 210);
				return;
			}
			finally {
				finallyTex(m1);
			}
			m1.done();
		}
		
		if (getStatus().getSeverity() < IStatus.ERROR) {
			try { // 28x
				if (getConfig().produce.isRun() && this.fTexOpenEditor > TexTab.OPEN_ALWAYS && this.fTexFile.findMaxProblemSeverity(IMarker.PROBLEM, true, IResource.DEPTH_ZERO) >= this.fTexOpenEditor) {
					final OpenUsingEclipseOperation operation= new OpenUsingEclipseOperation(this.fTexFile);
					try {
						operation.init(getConfig().produce, NO_SETTINGS, this.fProgress.newChild(1));
						operation.setFailSeverity(IStatus.WARNING);
						operation.run(this, this.fProgress.newChild(TICKS_OPEN_TEX - 1));
					}
					catch (final CoreException e) {}
				}
			}
			catch (final CoreException e) {
				abort(e, 280);
				return;
			}
		}
	}
	
	private void finallyTex(final SubMonitor m) {
		refreshDir(this.fTexPathConfig.getOutputFile(), m.isCanceled() ? null : m.newChild(5));
		if (!this.fWorkingFolderInWorkspace.equals(this.fTexPathConfig.getOutputFile().getParent())) {
			final Job job= new Job("Refresh after TeX build") {
				@Override
				protected IStatus run(final IProgressMonitor monitor) {
					return refreshDir(TexRweaveProcessToolProcess.this.fWorkingFolderInWorkspace, m.isCanceled() ? null : m.newChild(5));
				}
			};
			job.setSystem(true);
			final IResourceRuleFactory ruleFactory= this.fWorkingFolderInWorkspace.getWorkspace().getRuleFactory();
			job.setRule(ruleFactory.refreshRule(this.fWorkingFolderInWorkspace));
		}
	}
	
	private void doOpenOutput() { // 3xx
		final Config config= getConfig();
		if (config.preview.isRun()) {
			final SubMonitor m1= this.fProgress.newChild(TICKS_OPEN_OUTPUT);
			m1.setWorkRemaining(100);
			if (!this.fTexPathConfig.getOutputFile().exists()) {
				abort((config.preview.getRun() == RUN_EXPLICITE) ? IStatus.ERROR : IStatus.INFO,
						NLS.bind(Messages.RweaveTexProcessing_Output_error_NotFound_message, this.fTexPathConfig.getOutputFile().getFullPath().toString()), null,
						301);
				return;
			}
			try {
				if (config.preview.getRun() == RUN_DEFAULT && this.fTexFile.findMaxProblemSeverity(IMarker.PROBLEM, true, IResource.DEPTH_ZERO) >= IMarker.SEVERITY_ERROR) {
					abort(IStatus.CANCEL, Messages.RweaveTexProcessing_Output_info_SkipBecauseTex_message, null,
							302);
					return;
				}
			}
			catch (final CoreException e) {
				abort(e, 303);
				return;
			}
			m1.worked(10);
			if (this.fPreviewConfig != null) {
				Texlipse.getViewerManager().openDocInViewer(this.fTexPathConfig, this.fPreviewConfig);
			}
			else {
				final OpenUsingEclipseOperation operation= new OpenUsingEclipseOperation(
						this.fTexPathConfig.getOutputFile() );
				try {
					operation.init(getConfig().preview, NO_SETTINGS, m1);
					operation.run(this, m1);
				}
				catch (final CoreException e) {
					abort(e, 304);
				}
			}
			m1.done();
//			final ILaunchConfigurationDelegate delegate= getRunDelegate(fPreviewConfig);
//			delegate.launch(fPreviewConfig, ILaunchManager.RUN_MODE, fLaunch, new SubProgressMonitor(fMonitor, 10));
		}
	}
	
	private boolean checkExit(final int code) {
		if (getStatus().getSeverity() >= IStatus.ERROR) {
			if (code != 0 && doGetExitValue() == 0) {
				doSetExitValue(code);
			}
			return true;
		}
		if (this.fProgress.isCanceled()) {
			final IProgressMonitor p2= this.fProgress2;
			if (p2 != null && !p2.isCanceled()) {
				p2.setCanceled(true);
			}
			if (getStatus().getSeverity() < IStatus.CANCEL) { 
				getStatus().add(new Status(IStatus.CANCEL, TexRweaveUI.BUNDLE_ID, Messages.RweaveTexProcessing_info_Canceled_message));
			}
			return true;
		}
		else {
			final IProgressMonitor p2= this.fProgress2;
			if (p2 != null && p2.isCanceled()) {
				this.fProgress.setCanceled(true);
				if (getStatus().getSeverity() < IStatus.CANCEL) { 
					getStatus().add(new Status(IStatus.CANCEL, TexRweaveUI.BUNDLE_ID, Messages.RweaveTexProcessing_info_Canceled_message));
				}
				return true;
			}
		}
		return false;
	}
	
	private void abort(final CoreException e, final int exitCode) {
		final IStatus status= e.getStatus();
		if (status.getSeverity() == IStatus.CANCEL) {
			getStatus().add(status);
		}
		else {
			abort(status.getSeverity(), status.getMessage(), e, exitCode);
		}
	}
	
	private void abort(final int severity, final String message, final Throwable cause, final int exitValue) {
		getStatus().add(new Status(severity, TexRweaveUI.BUNDLE_ID, -1, message, cause));
		doSetExitValue(exitValue);
	}
	
	
	private IStatus refreshDir(final IResource resource, final IProgressMonitor monitor) {
		try {
			resource.refreshLocal(IResource.DEPTH_ONE, monitor);
			return Status.OK_STATUS;
		}
		catch (final OperationCanceledException e) {
			return new Status(IStatus.CANCEL, TexRweaveUI.BUNDLE_ID, -1,
					Messages.RweaveTexProcessing_info_Canceled_message, e);
		}
		catch (final CoreException e) {
			return e.getStatus();
		}
	}
	
	
	@Override
	public void terminate() throws DebugException {
		{	final IProgressMonitor monitor= this.fProgress2;
			if (monitor != null) {
				monitor.setCanceled(true);
			}
		}
		
		super.terminate();
	}
	
}
