/*=============================================================================#
 # Copyright (c) 2011, 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.rj.servi.rcpdemo;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.ecommons.ts.core.SystemRunnable;
import org.eclipse.statet.ecommons.ts.core.Tool;
import org.eclipse.statet.ecommons.ts.core.ToolQueue;
import org.eclipse.statet.ecommons.ts.core.ToolRunnable;
import org.eclipse.statet.ecommons.ts.core.ToolService;

import org.eclipse.statet.internal.rj.servi.RServiImpl;
import org.eclipse.statet.internal.rj.servi.rcpdemo.Activator;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.eclient.core.RToolService;
import org.eclipse.statet.rj.servi.RServi;
import org.eclipse.statet.rj.services.FunctionCall;
import org.eclipse.statet.rj.services.RGraphicCreator;
import org.eclipse.statet.rj.services.RPlatform;
import org.eclipse.statet.rj.services.RService;


/**
 * Implementations of ECommons Tool Service and Scheduling interfaces (org.eclipse.statet.ecommons.ts.core) for 
 * RServi using Eclipse jobs.
 */
public class RServiSession extends PlatformObject implements Tool {
	
	
	private class Queue implements ToolQueue {
		
		@Override
		public IStatus add(final ToolRunnable runnable) {
			synchronized (RServiSession.this.jobs) {
				if (isTerminated()) {
					return new Status(IStatus.ERROR, Activator.BUNDLE_ID,
							"The R session is terminated.");
				}
				if (!runnable.changed(ToolRunnable.ADDING_TO, RServiSession.this)) {
					return Status.CANCEL_STATUS;
				}
				final RunnableJob job= new RunnableJob(runnable);
				RServiSession.this.jobs.add(job);
				job.addJobChangeListener(RServiSession.this.jobListener);
				job.schedule();
				return Status.OK_STATUS;
			}
		}
		
		@Override
		public void remove(final ToolRunnable runnable) {
			RunnableJob removed= null;
			synchronized (RServiSession.this.jobs) {
				for (int i= 0; i < RServiSession.this.jobs.size(); i++) {
					final RunnableJob job= RServiSession.this.jobs.get(i);
					if (job.runnable == runnable) {
						if (job.runnable.changed(ToolRunnable.REMOVING_FROM, RServiSession.this)) {
							removed= job;
							RServiSession.this.jobs.remove(i);
							break;
						}
						return;
					}
				}
			}
			if (removed != null) {
				removed.cancel();
			}
		}
		
		@Override
		public boolean isHotSupported() {
			return false;
		}
		
		@Override
		public IStatus addHot(final ToolRunnable runnable) {
			return add(runnable);
		}
		
		@Override
		public void removeHot(final ToolRunnable runnable) {
			remove(runnable);
		}
		
	}
	
	private class RServiService implements RToolService, RService, ToolService {
		
		@Override
		public Tool getTool() {
			return RServiSession.this;
		}
		
		@Override
		public RPlatform getPlatform() {
			return RServiSession.this.servi.getPlatform();
		}
		
		@Override
		public void evalVoid(final String expression,
				final IProgressMonitor monitor) throws CoreException {
			RServiSession.this.servi.evalVoid(expression, monitor);
		}
		
		@Override
		public void evalVoid(final String expression, final RObject envir,
				final IProgressMonitor monitor) throws CoreException {
			RServiSession.this.servi.evalVoid(expression, envir, monitor);
		}
		
		@Override
		public RObject evalData(final String expression,
				final IProgressMonitor monitor) throws CoreException {
			return RServiSession.this.servi.evalData(expression, monitor);
		}
		
		@Override
		public RObject evalData(final String expression,
				final String factoryId, final int options, final int depth,
				final IProgressMonitor monitor) throws CoreException {
			return RServiSession.this.servi.evalData(expression, factoryId, options, depth, monitor);
		}
		
		@Override
		public RObject evalData(final String expression, final RObject envir,
				final String factoryId, final int options, final int depth,
				final IProgressMonitor monitor) throws CoreException {
			return RServiSession.this.servi.evalData(expression, envir, factoryId, options, depth, monitor);
		}
		
		@Override
		public RObject evalData(final RReference reference,
				final IProgressMonitor monitor) throws CoreException {
			return RServiSession.this.servi.evalData(reference, monitor);
		}
		
		@Override
		public RObject evalData(final RReference reference,
				final String factoryId, final int options, final int depth,
				final IProgressMonitor monitor) throws CoreException {
			return RServiSession.this.servi.evalData(reference, factoryId, options, depth, monitor);
		}
		
		@Override
		public void assignData(final String expression, final RObject data,
				final IProgressMonitor monitor) throws CoreException {
			RServiSession.this.servi.assignData(expression, data, monitor);
		}
		
		@Override
		public void uploadFile(final InputStream in, final long length, final String fileName,
				final int options, final IProgressMonitor monitor) throws CoreException {
			RServiSession.this.servi.uploadFile(in, length, fileName, options, monitor);
		}
		
		@Override
		public void downloadFile(final OutputStream out, final String fileName, final int options,
				final IProgressMonitor monitor) throws CoreException {
			RServiSession.this.servi.downloadFile(fileName, options, monitor);
		}
		
		@Override
		public byte[] downloadFile(final String fileName, final int options,
				final IProgressMonitor monitor) throws CoreException {
			return RServiSession.this.servi.downloadFile(fileName, options, monitor);
		}
		
		@Override
		public FunctionCall createFunctionCall(final String name) throws CoreException {
			return RServiSession.this.servi.createFunctionCall(name);
		}
		
		@Override
		public RGraphicCreator createRGraphicCreator(final int options) throws CoreException {
			return RServiSession.this.servi.createRGraphicCreator(options);
		}
		
	}
	
	private class RunnableJob extends Job {
		
		private final ToolRunnable runnable;
		
		public RunnableJob(final ToolRunnable runnable) {
			super(runnable.getLabel());
			this.runnable= runnable;
			setRule(RServiSession.this.schedulingRule);
			if (runnable instanceof SystemRunnable) {
				setSystem(true);
			}
		}
		
		@Override
		public boolean belongsTo(final Object family) {
			return (family == RServiSession.this);
		}
		
		@Override
		public boolean shouldRun() {
			synchronized (RServiSession.this.jobs) {
				return RServiSession.this.jobs.remove(this);
			}
		}
		
		@Override
		protected IStatus run(final IProgressMonitor monitor) {
			try {
				this.runnable.run(RServiSession.this.service, monitor);
				this.runnable.changed(ToolRunnable.FINISHING_OK, RServiSession.this);
				return Status.OK_STATUS;
			}
			catch (final CoreException e) {
				if (e.getStatus() != null && e.getStatus().getSeverity() == IStatus.CANCEL) {
					this.runnable.changed(ToolRunnable.FINISHING_CANCEL, RServiSession.this);
					return e.getStatus();
				}
				final Status status= new Status(IStatus.ERROR, Activator.BUNDLE_ID,
						"An error occurred when running " + getName() + ".", e);
				StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG);
				this.runnable.changed(ToolRunnable.FINISHING_ERROR, RServiSession.this);
				return status;
			}
		}
		
	}
	
	private class JobListener implements IJobChangeListener {
		
		@Override
		public void aboutToRun(final IJobChangeEvent event) {
		}
		
		@Override
		public void awake(final IJobChangeEvent event) {
		}
		
		@Override
		public void done(final IJobChangeEvent event) {
			if (event.getResult() == Status.CANCEL_STATUS) {
				synchronized (RServiSession.this.jobs) {
					if (RServiSession.this.jobs.remove(event.getJob())) {
						((RunnableJob) event.getJob()).runnable.changed(ToolRunnable.BEING_ABANDONED, RServiSession.this);
					}
				}
			}
		}
		
		@Override
		public void running(final IJobChangeEvent event) {
		}
		
		@Override
		public void scheduled(final IJobChangeEvent event) {
		}
		
		@Override
		public void sleeping(final IJobChangeEvent event) {
		}
		
	}
	
	
	private final Queue queue= new Queue();
	private final RServiService service= new RServiService();
	private final String label;
	
	private final ISchedulingRule schedulingRule;
	private int state;
	private RServi servi;
	
	private final List<RunnableJob> jobs= new ArrayList<>();
	private final IJobChangeListener jobListener= new JobListener();
	
	
	public RServiSession(final RServi servi) {
		this("R engine", servi, new ISchedulingRule() {
			@Override
			public boolean contains(final ISchedulingRule rule) {
				return (rule == this);
			}
			@Override
			public boolean isConflicting(final ISchedulingRule rule) {
				return (rule == this);
			}
		});
	}
	
	public RServiSession(final String label,
			final RServi servi, final ISchedulingRule schedulingRule) {
		this.label= label;
		this.servi= servi;
		this.schedulingRule= schedulingRule;
		
		doStart();
	}
	
	
	@Override
	public String getMainType() {
		return "R";
	}
	
	@Override
	public boolean isProvidingFeatureSet(final String featureSetId) {
		return "org.eclipse.statet.rj.services.RService".equals(featureSetId); //$NON-NLS-1$
	}
	
	@Override
	public ToolQueue getQueue() {
		return this.queue;
	}
	
	@Override
	public boolean isTerminated() {
		return (this.state < 0);
	}
	
	private void doStart() {
		if (this.servi != null) {
			((RServiImpl) this.servi).setRHandle(this);
			this.state= 1;
		}
		else {
			doTerminate();
		}
	}
	
	private void doTerminate() {
		if (this.servi != null) {
			try {
				this.servi.close();
			}
			catch (final CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			this.servi= null;
		}
		if (this.state != -2) {
			this.state= -2;
			terminated();
		}
	}
	
	protected void terminated() {
	}
	
	@Override
	public String getLabel(final int config) {
		return this.label;
	}
	
	public void close(final boolean immediately) {
		synchronized (this.jobs) {
			if (this.state < 0) {
				return;
			}
			if (immediately) {
				Job.getJobManager().cancel(this);
				for (int i= 0; i < this.jobs.size(); i++) {
					this.jobs.get(i).runnable.changed(ToolRunnable.BEING_ABANDONED, RServiSession.this);
				}
				this.jobs.clear();
			}
			this.queue.add(new SystemRunnable() {
				@Override
				public String getTypeId() {
					return "r/session/close";
				}
				@Override
				public String getLabel() {
					return "Close R Session";
				}
				@Override
				public boolean canRunIn(final Tool tool) {
					return (tool == RServiSession.this);
				}
				@Override
				public boolean changed(final int event, final Tool tool) {
					return true;
				}
				@Override
				public void run(final ToolService service,
						final IProgressMonitor monitor) throws CoreException {
					doTerminate();
				}
			});
			this.state= -1;
		}
	}
	
}
