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

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;

import javax.security.auth.login.LoginException;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.lang.Disposable;
import org.eclipse.statet.jcommons.rmi.RMIRegistry;
import org.eclipse.statet.jcommons.rmi.RMIRegistryManager;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.InfoStatus;
import org.eclipse.statet.jcommons.status.NullProgressMonitor;
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.ts.core.ToolRunnable;

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

import org.eclipse.statet.internal.rj.example.rcpdemo.Activator;
import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.eclient.graphics.comclient.ERClientGraphicActionsFactory;
import org.eclipse.statet.rj.rsetups.RSetup;
import org.eclipse.statet.rj.rsetups.RSetupUtil;
import org.eclipse.statet.rj.server.RjsComConfig;
import org.eclipse.statet.rj.server.client.RClientGraphicFactory;
import org.eclipse.statet.rj.server.eruntime.ERJContext;
import org.eclipse.statet.rj.servi.RServi;
import org.eclipse.statet.rj.servi.RServiUtils;
import org.eclipse.statet.rj.servi.node.RServiImpl;
import org.eclipse.statet.rj.servi.node.RServiNodeConfig;
import org.eclipse.statet.rj.servi.node.RServiNodeFactory;
import org.eclipse.statet.rj.servi.node.RServiNodeManager;
import org.eclipse.statet.rj.ts.core.RTool;


public class RServiManager implements Disposable {
	
	
	private static final int LOCAL_INST= 1;
	private static final int LOCAL_RSETUP= 2;
	private static final int POOL= 3;
	
	private static class Config {
		
		private int mode;
		private String address;
		
	}
	
	
	private final String name;
	
	private Config config= new Config();
	
	private RServiNodeManager localR;
	
	private RServiSession currentSession;
	private final List<RServiSession> runningSessions= new ArrayList<>();
	
	
	public RServiManager(final String appId, final RClientGraphicFactory graphicFactory) {
		this.name= appId;
		
		RjsComConfig.setProperty("rj.servi.graphicFactory", graphicFactory);
		RjsComConfig.setProperty("rj.servi.comClientGraphicActionsFactory",
				new ERClientGraphicActionsFactory() );
	}
	
	
	public void setLocalInst(final String rHome) throws StatusException {
		closeRServiSession();
		
		final Config config= new Config();
		config.mode= LOCAL_INST;
		config.address= rHome;
		this.config= config;
		
		final RServiNodeConfig rConfig= new RServiNodeConfig();
		rConfig.setRHome(rHome);
		rConfig.setEnableVerbose(true);
		
		startLocal(rConfig);
	}
	
	public void setRSetup(final String setupId) throws StatusException {
		closeRServiSession();
		
		final Config config= new Config();
		config.mode= LOCAL_RSETUP;
		config.address= setupId;
		this.config= config;
		
		final RSetup setup= RSetupUtil.loadSetup(setupId, null);
		if (setup == null) {
			throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
					"No R setup with specified id found." ));
		}
		
		final RServiNodeConfig rConfig= new RServiNodeConfig();
		rConfig.setRHome(setup.getRHome());
		setLibs(setup.getRLibsSite(), rConfig, "R_LIBS_SITE");
		setLibs(setup.getRLibs(), rConfig, "R_LIBS");
		setLibs(setup.getRLibsUser(), rConfig, "R_LIBS_USER");
		rConfig.setEnableVerbose(true);
		
		startLocal(rConfig);
	}
	
	public void setPool(final String poolAddress) {
		closeRServiSession();
		
		final Config config= new Config();
		config.mode= POOL;
		config.address= poolAddress;
		this.config= config;
	}
	
	
	private void setLibs(final List<String> locations, final RServiNodeConfig rConfig, final String varName) {
		if (locations != null && locations.size() > 0) {
			final StringBuilder sb= new StringBuilder(locations.get(0));
			for (int i= 0; i < locations.size(); i++) {
				sb.append(File.pathSeparatorChar);
				sb.append(locations.get(i));
			}
			rConfig.getEnvironmentVariables().put(varName, sb.toString());
		}
	}
	
	private void startLocal(final RServiNodeConfig rConfig) throws StatusException {
		startLocal(rConfig, new NullProgressMonitor()); // TODO real monitor, e.g. in a Job
	}
	
	private void startLocal(final RServiNodeConfig rConfig,
			final ProgressMonitor m) throws StatusException {
		if (rConfig == null) {
			throw new NullPointerException("rConfig");
		}
		if (m == null) {
			throw new NullPointerException("monitor");
		}
		try {
			final ERJContext context= new ERJContext();
			if (System.getSecurityManager() == null) {
				if (System.getProperty("java.security.policy") == null) {
					final String policyFile= context.getServerPolicyFilePath();
					System.setProperty("java.security.policy", policyFile);
				}
				System.setSecurityManager(new SecurityManager());
			}
			
			final RMIRegistry registry= RMIRegistryManager.INSTANCE.getEmbeddedPrivateRegistry(m);
			
			final RServiNodeFactory nodeFactory= RServiImpl.createLocalNodeFactory(this.name, context);
			nodeFactory.setRegistry(registry);
			nodeFactory.setConfig(rConfig);
			
			final RServiNodeManager newLocalR= RServiImpl.createNodeManager(this.name, registry, nodeFactory);
			newLocalR.start();
			if (this.localR != null) {
				this.localR.stop();
				this.localR= null;
			}
			this.localR= newLocalR;
		}
		catch (final RjException e) {
			throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
					"Local R instance could not created.", e ));
		}
	}
	
	
	public synchronized RTool getRServiSession() throws StatusException {
		if (this.currentSession == null) {
			final RServi servi= getRServi("session");
			this.currentSession= new RServiSession(servi) {
				@Override
				protected void terminated() {
					synchronized (RServiManager.this.runningSessions) {
						RServiManager.this.runningSessions.remove(this);
					}
				}
			};
			synchronized (this.runningSessions) {
				this.runningSessions.add(this.currentSession);
			}
		}
		return this.currentSession;
	}
	
	private void closeRServiSession() {
		if (this.currentSession != null) {
			this.currentSession.close(false);
			this.currentSession= null;
		}
	}
	
	
	public void schedule(final ToolRunnable runnable) throws StatusException {
		final RTool session= getRServiSession();
		final Status status;
		if (session != null) {
			status= session.getQueue().add(runnable);
		}
		else {
			status= new ErrorStatus(Activator.BUNDLE_ID, "R engine not available.");
		}
		if (status.getSeverity() != Status.OK) {
			throw new StatusException(status);
		}
	}
	
	public void scheduleDemo(final ToolRunnable runnable) {
		try {
			schedule(runnable);
		}
		catch (final StatusException e) {
			final IStatus status= new org.eclipse.core.runtime.Status(e.getStatus().getSeverity(), Activator.BUNDLE_ID,
					"Cannot schedule '" + runnable.getLabel() + "'", StatusUtils.convert(e) );
			StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG);
		}
	}
	
	@Override
	public void dispose() {
		this.config= new Config();
		final RServiSession[] sessions;
		synchronized (this.runningSessions) {
			sessions= this.runningSessions.toArray(new RServiSession[this.runningSessions.size()]);
		}
		for (final RServiSession session : sessions) {
			session.close(true);
		}
	}
	
	private RServi getRServi(final String task) throws StatusException {
		final Config config= this.config;
		final String key= this.name + "-" + task;
		
		try {
			switch (config.mode) {
			case LOCAL_INST:
			case LOCAL_RSETUP:
				return RServiUtils.getRServi(this.localR, key);
			case POOL:
				return RServiUtils.getRServi(config.address, key);
			default:
				throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
						"R is not configured, please check the configuration." ));
			}
		}
		catch (final StatusException e) {
			throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
					"R not available, please check the configuration.",
					e ));
		}
		catch (final LoginException e) {
			throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
					"R not available, please check the configuration.",
					e ));
		}
		catch (final NoSuchElementException e) {
			throw new StatusException(new InfoStatus(Activator.BUNDLE_ID,
					"R currently not available, please try again later.",
					e ));
		}
	}
	
}
