/*=============================================================================#
 # Copyright (c) 2009, 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.rj.servi.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.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.lang.Disposable;

import org.eclipse.statet.ecommons.rmi.core.RMIRegistry;
import org.eclipse.statet.ecommons.rmi.core.RMIRegistryManager;
import org.eclipse.statet.ecommons.ts.core.Tool;
import org.eclipse.statet.ecommons.ts.core.ToolRunnable;

import org.eclipse.statet.internal.rj.servi.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.osgi.ERJContext;
import org.eclipse.statet.rj.servi.RServi;
import org.eclipse.statet.rj.servi.RServiUtil;
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;


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 CoreException {
		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 CoreException {
		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 CoreException(new Status(IStatus.ERROR, 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 CoreException {
		startLocal(rConfig, new NullProgressMonitor()); // TODO real monitor, e.g. in a Job
	}
	
	private void startLocal(final RServiNodeConfig rConfig,
			final IProgressMonitor monitor) throws CoreException {
		if (rConfig == null) {
			throw new NullPointerException("rConfig");
		}
		if (monitor == 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(monitor);
			
			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 CoreException(new Status(IStatus.ERROR, Activator.BUNDLE_ID, "Local R instance could not created.", e));
		}
	}
	
	
	public synchronized Tool getRServiSession() throws CoreException {
		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 CoreException {
		final Tool session= getRServiSession();
		final IStatus status;
		if (session != null) {
			status= session.getQueue().add(runnable);
		}
		else {
			status= new Status(IStatus.ERROR, Activator.BUNDLE_ID,
					"R engine not available.");
		}
		if (!status.isOK()) {
			throw new CoreException(status);
		}
	}
	
	public void scheduleDemo(final ToolRunnable runnable) {
		try {
			schedule(runnable);
		}
		catch (final CoreException e) {
			final Status status= new Status(e.getStatus().getSeverity(), Activator.BUNDLE_ID,
					"Cannot schedule '" + runnable.getLabel() + "'", 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 CoreException {
		final Config config= this.config;
		final String key= this.name + "-" + task;
		
		try {
			switch (config.mode) {
			case LOCAL_INST:
			case LOCAL_RSETUP:
				return RServiUtil.getRServi(this.localR, key);
			case POOL:
				return RServiUtil.getRServi(config.address, key);
			}
		}
		catch (final CoreException e) {
			throw new CoreException(new Status(IStatus.ERROR, Activator.BUNDLE_ID, "R not available, please check the configuration.", e));
		}
		catch (final LoginException e) {
			throw new CoreException(new Status(IStatus.ERROR, Activator.BUNDLE_ID, "R not available, please check the configuration.", e));
		}
		catch (final NoSuchElementException e) {
			throw new CoreException(new Status(IStatus.INFO, Activator.BUNDLE_ID, "R currently not available, please try again later.", e));
		}
		throw new CoreException(new Status(IStatus.ERROR, Activator.BUNDLE_ID, "R is not configured, please check the configuration."));
	}
	
}
