/*=============================================================================#
 # 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.example.rcpdemo;

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

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.PlatformObject;
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.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.status.Statuses;
import org.eclipse.statet.jcommons.ts.core.SystemRunnable;
import org.eclipse.statet.jcommons.ts.core.Tool;
import org.eclipse.statet.jcommons.ts.core.ToolQueue;
import org.eclipse.statet.jcommons.ts.core.ToolRunnable;
import org.eclipse.statet.jcommons.ts.core.ToolService;

import org.eclipse.statet.ecommons.runtime.core.util.StatusUtils;

import org.eclipse.statet.internal.rj.example.rcpdemo.Activator;
import org.eclipse.statet.internal.rj.servi.RServiImpl;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.servi.RServi;
import org.eclipse.statet.rj.services.FQRObject;
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.ts.core.RTool;
import org.eclipse.statet.rj.ts.core.RToolService;


/**
 * Implementations of ECommons Tool Service and Scheduling interfaces (org.eclipse.statet.jcommons.ts.core) for
 * RServi using Eclipse jobs.
 */
@NonNullByDefault
public class RServiSession extends PlatformObject implements RTool {
	
	
	private class Queue implements ToolQueue {
		
		@Override
		public Status add(final ToolRunnable runnable) {
			synchronized (RServiSession.this.jobs) {
				if (isTerminated()) {
					return new ErrorStatus(Activator.BUNDLE_ID,
							"The R session is terminated.");
				}
				if (!runnable.changed(ToolRunnable.ADDING_TO, RServiSession.this)) {
					return Statuses.CANCEL_STATUS;
				}
				final RunnableJob job= new RunnableJob(runnable);
				RServiSession.this.jobs.add(job);
				job.addJobChangeListener(RServiSession.this.jobListener);
				job.schedule();
				return Statuses.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 Status addHot(final ToolRunnable runnable) {
			return add(runnable);
		}
		
		@Override
		public void removeHot(final ToolRunnable runnable) {
			remove(runnable);
		}
		
	}
	
	private class RServiService implements RToolService {
		
		@Override
		public RTool getTool() {
			return RServiSession.this;
		}
		
		@Override
		public RPlatform getPlatform() {
			return RServiSession.this.servi.getPlatform();
		}
		
		@Override
		public void evalVoid(final String expression,
				final ProgressMonitor m) throws StatusException {
			RServiSession.this.servi.evalVoid(expression, m);
		}
		
		@Override
		public void evalVoid(final String expression, final @Nullable RObject envir,
				final ProgressMonitor m) throws StatusException {
			RServiSession.this.servi.evalVoid(expression, envir, m);
		}
		
		@Override
		public RObject evalData(final String expression,
				final ProgressMonitor m) throws StatusException {
			return RServiSession.this.servi.evalData(expression, m);
		}
		
		@Override
		public RObject evalData(final String expression,
				final @Nullable String factoryId, final int options, final int depth,
				final ProgressMonitor m) throws StatusException {
			return RServiSession.this.servi.evalData(expression, factoryId, options, depth, m);
		}
		
		@Override
		public RObject evalData(final String expression, final @Nullable RObject envir,
				final @Nullable String factoryId, final int options, final int depth,
				final ProgressMonitor m) throws StatusException {
			return RServiSession.this.servi.evalData(expression, envir, factoryId, options, depth, m);
		}
		
		@Override
		public RObject evalData(final RReference reference,
				final ProgressMonitor m) throws StatusException {
			return RServiSession.this.servi.evalData(reference, m);
		}
		
		@Override
		public RObject evalData(final RReference reference,
				final @Nullable String factoryId, final int options, final int depth,
				final ProgressMonitor m) throws StatusException {
			return RServiSession.this.servi.evalData(reference, factoryId, options, depth, m);
		}
		
		@Override
		public @Nullable FQRObject<RTool> findData(final String symbol, final @Nullable RObject env, final boolean inherits,
				final @Nullable String factoryId, final int options, final int depth,
				final ProgressMonitor m) throws StatusException {
			return (FQRObject<RTool>) RServiSession.this.servi.findData(symbol, env, inherits,
					factoryId, options, depth, m );
		}
		
		@Override
		public void assignData(final String expression, final RObject data,
				final ProgressMonitor m) throws StatusException {
			RServiSession.this.servi.assignData(expression, data, m);
		}
		
		@Override
		public void uploadFile(final InputStream in, final long length, final String fileName,
				final int options, final ProgressMonitor m) throws StatusException {
			RServiSession.this.servi.uploadFile(in, length, fileName, options, m);
		}
		
		@Override
		public void downloadFile(final OutputStream out, final String fileName, final int options,
				final ProgressMonitor m) throws StatusException {
			RServiSession.this.servi.downloadFile(fileName, options, m);
		}
		
		@Override
		public byte[] downloadFile(final String fileName, final int options,
				final ProgressMonitor m) throws StatusException {
			return RServiSession.this.servi.downloadFile(fileName, options, m);
		}
		
		@Override
		public FunctionCall createFunctionCall(final String name) throws StatusException {
			return RServiSession.this.servi.createFunctionCall(name);
		}
		
		@Override
		public RGraphicCreator createRGraphicCreator(final int options) throws StatusException {
			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) {
			final ProgressMonitor m= StatusUtils.convert(monitor, 1);
			try {
				this.runnable.run(RServiSession.this.service, m);
				this.runnable.changed(ToolRunnable.FINISHING_OK, RServiSession.this);
				return org.eclipse.core.runtime.Status.OK_STATUS;
			}
			catch (final StatusException e) {
				if (e.getStatus() != null && e.getStatus().getSeverity() == IStatus.CANCEL) {
					this.runnable.changed(ToolRunnable.FINISHING_CANCEL, RServiSession.this);
					return StatusUtils.convert(e.getStatus());
				}
				final IStatus status= new org.eclipse.core.runtime.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().getSeverity() == IStatus.CANCEL) {
				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 featureId) {
		return R_SERVICE_FEATURE_ID.equals(featureId);
	}
	
	@Override
	public ToolQueue getQueue() {
		return this.queue;
	}
	
	@Override
	public boolean isTerminated() {
		return (this.state < 0);
	}
	
	private void doStart() {
		if (this.servi != null) {
			((RServiImpl<RTool>) this.servi).setRHandle(this);
			this.state= 1;
		}
		else {
			doTerminate();
		}
	}
	
	private void doTerminate() {
		if (this.servi != null) {
			try {
				this.servi.close();
			}
			catch (final StatusException 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 ProgressMonitor m) throws StatusException {
					doTerminate();
				}
			});
			this.state= -1;
		}
	}
	
}
