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

import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.StatusException;

import org.eclipse.statet.internal.rj.servi.Utils;
import org.eclipse.statet.rj.renv.core.DefaultLocalConfigurator;
import org.eclipse.statet.rj.renv.core.REnvConfiguration;


/**
 * Configuration for an R node.
 */
@NonNullByDefault
public class RServiNodeConfig implements PropertiesBean {
	
	
	public static final String BEAN_ID= "rconfig";
	
	public static final String R_HOME_ID= "r_home.path";
	
	public static final String R_ARCH_ID= "r_arch.code";
	
	public static final String JAVA_HOME_ID= "java_home.path";
	
	public static final String JAVA_ARGS_ID= "java_cmd.args";
	private static final String JAVA_ARGS_OLD_ID= "java_args.path";
	
	public static final String NODE_ENVIRONMENT_VARIABLES_PREFIX= "node_environment.variables.";
	public static final String NODE_ARGS_ID= "node_cmd.args";
	
	public static final String BASE_WD_ID= "base_wd.path";
	
	/**
	 * Property id for R startup snippet
	 * 
	 * @see #setRStartupSnippet(String)
	 * @since 0.5
	 */
	public static final String R_STARTUP_SNIPPET_ID= "r_startup.snippet";
	
	public static final String CONSOLE_ENABLED_ID= "debug_console.enabled";
	
	public static final String VERBOSE_ENABLED_ID= "debug_verbose.enabled";
	
	/**
	 * Property id for timeout of start/stop of nodes
	 * 
	 * @see #setStartStopTimeout(long)
	 * @since 2.0
	 */
	public static final String STARTSTOP_TIMEOUT__ID= "startstop_timeout.millis";
	
	private static final long STARTSTOP_TIMEOUT_DEFAULT= 30 * 1000;
	
	
	private @Nullable String rHome;
	private @Nullable String rArch;
	
	private @Nullable String javaHome;
	private String javaArgs;
	
	private final Map<String, String> environmentVariables= new HashMap<>();
	private String nodeArgs;
	
	private @Nullable String baseWd;
	
	private String rStartupSnippet;
	
	private boolean enableConsole;
	private boolean enableVerbose;
	
	private long startStopTimeout;
	
	
	public RServiNodeConfig() {
		this.rHome= System.getenv("R_HOME");
		this.rArch= System.getenv("R_ARCH");
		this.javaArgs= "-server";
		this.nodeArgs= "";
		this.rStartupSnippet= "";
		this.startStopTimeout= STARTSTOP_TIMEOUT_DEFAULT;
	}
	
	public RServiNodeConfig(final RServiNodeConfig config) {
		this();
		synchronized (config) {
			load(config);
		}
	}
	
	
	@Override
	public String getBeanId() {
		return BEAN_ID;
	}
	
	public synchronized void load(final RServiNodeConfig templ) {
		this.rHome= templ.rHome;
		this.rArch= templ.rArch;
		this.javaHome= templ.javaHome;
		this.javaArgs= templ.javaArgs;
		this.environmentVariables.clear();
		this.environmentVariables.putAll(templ.environmentVariables);
		this.nodeArgs= templ.nodeArgs;
		this.baseWd= templ.baseWd;
		this.rStartupSnippet= templ.rStartupSnippet;
		this.enableConsole= templ.enableConsole;
		this.enableVerbose= templ.enableVerbose;
		this.startStopTimeout= templ.startStopTimeout;
	}
	
	public synchronized void load(final REnvConfiguration config) throws StatusException {
		final DefaultLocalConfigurator configurator= new DefaultLocalConfigurator(config);
		
		setRHome(config.getRHomeDirectoryPath().toString());
		setRArch(configurator.getRArch());
		this.environmentVariables.clear();
		this.environmentVariables.putAll(configurator.getEnvironmentsVariables(0));
	}
	
	@Override
	public synchronized void load(final Properties map) {
		setRHome(map.getProperty(R_HOME_ID));
		setRArch(map.getProperty(R_ARCH_ID));
		setJavaHome(map.getProperty(JAVA_HOME_ID));
		setJavaArgs(map.getProperty(JAVA_ARGS_ID));
		if (this.javaArgs.length() == 0) {
			setJavaArgs(map.getProperty(JAVA_ARGS_OLD_ID));
		}
		this.environmentVariables.clear();
		final int prefixLength= NODE_ENVIRONMENT_VARIABLES_PREFIX.length();
		for (final Entry<Object, Object> p : map.entrySet()) {
			final String name= (String) p.getKey();
			if (name != null && name.length() > prefixLength
					&& name.startsWith(NODE_ENVIRONMENT_VARIABLES_PREFIX)
					&& p.getValue() instanceof String) {
				this.environmentVariables.put(name.substring(prefixLength), (String) p.getValue());
			}
		}
		setNodeArgs(map.getProperty(NODE_ARGS_ID));
		setBaseWorkingDirectory(map.getProperty(BASE_WD_ID));
		setRStartupSnippet(map.getProperty(R_STARTUP_SNIPPET_ID));
		setEnableConsole(Boolean.parseBoolean(map.getProperty(CONSOLE_ENABLED_ID)));
		setEnableVerbose(Boolean.parseBoolean(map.getProperty(VERBOSE_ENABLED_ID)));
		{	final String s= map.getProperty(STARTSTOP_TIMEOUT__ID);
			this.startStopTimeout= ((s != null) ? Long.parseLong(s) : STARTSTOP_TIMEOUT_DEFAULT);
		}
	}
	
	@Override
	public synchronized void save(final Properties map) {
		Utils.setProperty(map, R_HOME_ID, this.rHome);
		Utils.setProperty(map, R_ARCH_ID, this.rArch);
		Utils.setProperty(map, JAVA_HOME_ID, this.javaHome);
		Utils.setProperty(map, JAVA_ARGS_ID, this.javaArgs);
		for (final Entry<String, String> variable : this.environmentVariables.entrySet()) {
			map.setProperty(NODE_ENVIRONMENT_VARIABLES_PREFIX + variable.getKey(), variable.getValue());
		}
		Utils.setProperty(map, NODE_ARGS_ID, this.nodeArgs);
		Utils.setProperty(map, BASE_WD_ID, this.baseWd);
		Utils.setProperty(map, R_STARTUP_SNIPPET_ID, this.rStartupSnippet);
		Utils.setProperty(map, CONSOLE_ENABLED_ID, Boolean.toString(this.enableConsole));
		Utils.setProperty(map, VERBOSE_ENABLED_ID, Boolean.toString(this.enableVerbose));
		Utils.setProperty(map, STARTSTOP_TIMEOUT__ID, Long.toString(this.startStopTimeout));
	}
	
	public synchronized void setRHome(final @Nullable String path) {
		this.rHome= path;
	}
	
	public synchronized @Nullable String getRHome() {
		return this.rHome;
	}
	
	public synchronized void setRArch(final @Nullable String code) {
		this.rArch= code;
	}
	
	public synchronized @Nullable String getRArch() {
		return this.rArch;
	}
	
	public synchronized @Nullable String getJavaHome() {
		return this.javaHome;
	}
	
	public synchronized void setJavaHome(final @Nullable String javaHome) {
		this.javaHome= (javaHome != null && javaHome.trim().length() > 0) ? javaHome : null;
	}
	
	public synchronized String getJavaArgs() {
		return this.javaArgs;
	}
	
	public synchronized void setJavaArgs(final @Nullable String args) {
		this.javaArgs= (args != null) ? args : "";
	}
	
	/**
	 * Additional environment variables for the R process.
	 * 
	 * @return a name - value map of the environment variables
	 */
	public synchronized Map<String, String> getEnvironmentVariables() {
		return this.environmentVariables;
	}
	
	public synchronized void addToClasspath(final String entry) {
		String cp= this.environmentVariables.get("CLASSPATH");
		if (cp != null) {
			cp+= File.pathSeparatorChar + entry;
		}
		else {
			cp= entry;
		}
		this.environmentVariables.put("CLASSPATH", cp);
	}
	
	public synchronized String getNodeArgs() {
		return this.nodeArgs;
	}
	
	public synchronized void setNodeArgs(final @Nullable String args) {
		this.nodeArgs= (args != null) ? args : "";
	}
	
	public synchronized void setBaseWorkingDirectory(final @Nullable String path) {
		this.baseWd= (path != null && path.trim().length() > 0) ? path : null;
	}
	
	public synchronized @Nullable String getBaseWorkingDirectory() {
		return this.baseWd;
	}
	
	/**
	 * Returns the R code snippet to run at startup of a node.
	 * 
	 * @return the code
	 * 
	 * @see #setRStartupSnippet(String)
	 * @since 0.5
	 */
	public synchronized String getRStartupSnippet() {
		return this.rStartupSnippet;
	}
	
	/**
	 * Sets the R code snippet to run at startup of a node.
	 * <p>
	 * Typical use case is to load required R packages. The default is an empty snippet.
	 * If the execution of the code throws an error, the startup of the node is canceled.</p>
	 * 
	 * @param code the R code to run
	 * 
	 * @since 0.5
	 */
	public synchronized void setRStartupSnippet(final @Nullable String code) {
		this.rStartupSnippet= (code != null) ? code : "";
	}
	
	public synchronized boolean getEnableConsole() {
		return this.enableConsole;
	}
	
	public synchronized void setEnableConsole(final boolean enable) {
		this.enableConsole= enable;
	}
	
	public synchronized boolean getEnableVerbose() {
		return this.enableVerbose;
	}
	
	public synchronized void setEnableVerbose(final boolean enable) {
		this.enableVerbose= enable;
	}
	
	/**
	 * Returns the timeout of start/stop of nodes
	 * 
	 * @return the timeout in milliseconds
	 * 
	 * @since 2.0
	 */
	public long getStartStopTimeout() {
		return this.startStopTimeout;
	}
	
	/**
	 * Sets the timeout of start/stop of nodes
	 * 
	 * @param milliseconds the timeout in milliseconds
	 * 
	 * @since 2.0
	 */
	public void setStartStopTimeout(final long milliseconds) {
		this.startStopTimeout= milliseconds;
	}
	
	
	@Override
	public synchronized boolean validate(final @Nullable Collection<ValidationMessage> messages) {
		boolean valid= true;
		
		if (this.rHome != null && !new File(this.rHome).exists()) {
			if (messages != null) {
				messages.add(new ValidationMessage(R_HOME_ID, "The directory does not exist."));
			}
			valid= false;
		}
		if (this.javaHome != null && !new File(this.javaHome).exists()) {
			if (messages != null) {
				messages.add(new ValidationMessage(JAVA_HOME_ID, "The directory does not exist."));
			}
			valid= false;
		}
		if (this.baseWd != null && !new File(this.baseWd).exists()) {
			if (messages != null) {
				messages.add(new ValidationMessage(BASE_WD_ID, "The directory does not exist."));
			}
			valid= false;
		}
		
		if (this.startStopTimeout != -1 && this.startStopTimeout < 0) {
			if (messages != null) {
				messages.add(new ValidationMessage(STARTSTOP_TIMEOUT__ID, "Value must be > 0 or -1 (infinite)."));
			}
			valid= false;
		}
		
		return valid;
	}
	
}
