/*=============================================================================#
 # Copyright (c) 2008, 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.internal.r.console.ui.launching;

import java.io.File;
import java.net.InetAddress;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstall3;
import org.eclipse.jdt.launching.JavaLaunchDelegate;
import org.eclipse.jdt.launching.JavaRuntime;

import org.eclipse.statet.jcommons.collections.CollectionUtils;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.ObjectUtils;
import org.eclipse.statet.jcommons.runtime.bundle.BundleEntry;
import org.eclipse.statet.jcommons.runtime.bundle.BundleSpec;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.status.eplatform.EStatusUtils;

import org.eclipse.statet.ecommons.debug.core.util.LaunchUtils;

import org.eclipse.statet.internal.r.console.ui.RConsoleUIPlugin;
import org.eclipse.statet.nico.core.runtime.ToolRunner;
import org.eclipse.statet.r.core.renv.IREnvConfiguration;
import org.eclipse.statet.r.launching.ui.REnvTab;
import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.RjInvalidConfigurationException;
import org.eclipse.statet.rj.renv.core.RLibGroup;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.server.util.LocalREnv;
import org.eclipse.statet.rj.server.util.RJContext;
import org.eclipse.statet.rj.server.util.ServerUtils;


/**
 * Launches RJ Server using JDT java launch mechanism
 */
public class RJEngineLaunchDelegate extends JavaLaunchDelegate {
	
	
	private static final ImList<BundleSpec> CLASSPATH_LIB_SPECS= ImCollections.addElement(
			ServerUtils.MIN_CLASSPATH_SPECS,
			new BundleSpec("org.eclipse.swt") );
	
	private static final ImList<BundleSpec> CODEBASE_LIB_SPECS=
			ServerUtils.MIN_RMI_CODEBASE_SPECS;
	
	private static final String PATH_SPLITTER= Pattern.compile(File.pathSeparator, Pattern.LITERAL).pattern();
	
	
	private final String address;
	private final IREnvConfiguration rEnvConfig;
	private final List<BundleSpec> codebaseLibs;
	
	private final RJContext serverContext;
	private final LocalREnv serverREnv;
	private final Path rjPkgPath;
	
	private File workingDirectory;
	
	private IProgressMonitor monitor;
	
	
	private String libPreloadVar;
	private String libPreloadFile;
	
	
	public RJEngineLaunchDelegate(final String address, final boolean requireCodebase,
			final IREnvConfiguration rEnvConfig) throws CoreException {
		this.address= address;
		this.rEnvConfig= rEnvConfig;
		this.codebaseLibs= (requireCodebase) ? CODEBASE_LIB_SPECS : null;
		
		this.serverContext= new RJContext();
		
		try {
			final List<Path> rLibPaths= new ArrayList<>();
			for (final RLibGroup group : this.rEnvConfig.getRLibGroups()) {
				for (final RLibLocation library : group.getLibLocations()) {
					final Path path= library.getDirectoryPath();
					if (path != null) {
						rLibPaths.add(path);
					}
				}
			}
			this.serverREnv= new LocalREnv(Paths.get(this.rEnvConfig.getRHomeDirectory()), rLibPaths);
			
			this.rjPkgPath= this.serverREnv.searchRPkg("rj");
			if (this.rjPkgPath == null) {
				throw new CoreException(new Status(IStatus.ERROR, RConsoleUIPlugin.BUNDLE_ID,
						"Could not find the R package 'rj' in the R library path:" + 
								CollectionUtils.toString(rLibPaths, "\n\t") ));
			}
		}
		catch (final RjInvalidConfigurationException e) {
			throw new CoreException(new Status(IStatus.ERROR, RConsoleUIPlugin.BUNDLE_ID,
					"An error occurred when initializing the R library paths.",
					e ));
		}
		
		setLibPreload(true);
	}
	
	
	@Override
	public void launch(final ILaunchConfiguration configuration, String mode,
			final ILaunch launch, final IProgressMonitor monitor) throws CoreException {
		this.monitor= (monitor != null) ? monitor : new NullProgressMonitor();
		if (mode.equals(ILaunchManager.DEBUG_MODE)) {
			// TODO add configuration option (-> source lookup support for Java)
			mode= ILaunchManager.RUN_MODE;
		}
		super.launch(configuration, mode, launch, this.monitor);
	}
	@Override
	public IPath getWorkingDirectoryPath(final ILaunchConfiguration configuration) throws CoreException {
		final IFileStore workingDirectory= REnvTab.getWorkingDirectory(configuration);
		return URIUtil.toPath(workingDirectory.toURI());
	}
	
	@Override
	public File verifyWorkingDirectory(final ILaunchConfiguration configuration) throws CoreException {
		return this.workingDirectory= super.verifyWorkingDirectory(configuration);
	}
	
	public IFileStore getWorkingDirectory() {
		if (this.workingDirectory != null) {
			return EFS.getLocalFileSystem().fromLocalFile(this.workingDirectory);
		}
		return null;
	}
	
	public void setLibPreload(final boolean enable) {
		if (enable) {
			if (Platform.getOS().equals(Platform.OS_WIN32)) {
				this.libPreloadVar= null;
				this.libPreloadFile= null;
			}
			else if (Platform.getOS().equals(Platform.OS_MACOSX)) {
				this.libPreloadVar= null;
	//			fLibPreloadFile= "DYLD_INSERT_LIBRARIES"; //$NON-NLS-1$
				this.libPreloadFile= "libjsig.dylib"; //$NON-NLS-1$
			}
			else { // *nix
				this.libPreloadVar= "LD_PRELOAD"; //$NON-NLS-1$
				this.libPreloadFile= "libjsig.so"; //$NON-NLS-1$
			}
		}
		else {
			this.libPreloadVar= null;
			this.libPreloadFile= null;
		}
	}
	
	@Override
	public String[] getEnvironment(final ILaunchConfiguration configuration) throws CoreException {
		final IVMInstall vmInstall= getVMInstall(configuration); // already verified
		
		final Map<String, String> additional= new HashMap<>();
		final File location= vmInstall.getInstallLocation();
		if (location != null) {
			additional.put("JAVA_HOME", location.getAbsolutePath()); //$NON-NLS-1$
		}
		
		@SuppressWarnings("unchecked")
		final Map<String, String> envp= LaunchUtils.createEnvironment(configuration,
				new Map[] { additional, this.rEnvConfig.getEnvironmentsVariables() });
		
		if (this.libPreloadVar != null) {
			String value= envp.get(this.libPreloadVar);
			if (value == null || !value.contains("libjsig")) { //$NON-NLS-1$
				final String path= ((IVMInstall3) vmInstall).evaluateSystemProperties(
						new String[] { "java.library.path" }, this.monitor).get("java.library.path"); //$NON-NLS-1$ //$NON-NLS-2$
				if (path != null) {
					final String[] pathList= path.split(PATH_SPLITTER);
					for (int i= 0; i < pathList.length; i++) {
						final File file= new File(pathList[i], this.libPreloadFile);
						if (file.exists()) {
							final String s= file.getAbsolutePath();
							if (s.indexOf(' ') < 0) { // whitespace is separator char
								if (value != null && value.length() > 0) {
									value= s + ' ' + value;
								}
								else {
									value= s;
								}
								envp.put(this.libPreloadVar, value);
							}
							break;
						}
					}
				}
			}
		}
		
		return LaunchUtils.toKeyValueStrings(envp);
	}
	
	@Override
	public String[][] getClasspathAndModulepath(final ILaunchConfiguration configuration) throws CoreException {
		final String[][] paths= new String[2][];
		paths[0]= getClasspath(configuration);
		paths[1]= new String[0];
		return paths;
	}
	
	@Override
	public String[] getClasspath(final ILaunchConfiguration configuration) throws CoreException {
		final LinkedHashSet<String> classpath= new LinkedHashSet<>();
		classpath.add(this.rjPkgPath.resolve(Paths.get("server/rj-boot.jar")).toString());
		classpath.addAll(Arrays.asList(super.getClasspath(configuration)));
		return classpath.toArray(new String[classpath.size()]);
	}
	
	@Override
	public String getVMArguments(final ILaunchConfiguration configuration) throws CoreException {
		try {
			final String args= super.getVMArguments(configuration);
			final StringBuilder s= new StringBuilder(" "); //$NON-NLS-1$
			if (args != null) {
				s.append(args);
			}
			
			if (s.indexOf(" -D" + RJContext.RJ_SERVER_CLASS_PATH_PROPERTY_KEY + "=") < 0) { //$NON-NLS-1$ //$NON-NLS-2$
				s.append(" -D" + RJContext.RJ_SERVER_CLASS_PATH_PROPERTY_KEY + "=\""); //$NON-NLS-1$ //$NON-NLS-2$
				final List<BundleEntry> rjLibs= this.serverContext.resolveBundles(CLASSPATH_LIB_SPECS);
				s.append(ServerUtils.concatRJClassPath(rjLibs));
				s.append("\""); //$NON-NLS-1$
			}
			
			if (s.indexOf(" -Djava.security.policy=") < 0) { //$NON-NLS-1$
				s.append(" -Djava.security.policy="); //$NON-NLS-1$
				s.append('"');
				s.append(this.serverContext.getServerPolicyFilePath());
				s.append('"');
			}
			// RMI
			if (s.indexOf(" -Djava.rmi.server.hostname=") < 0) { //$NON-NLS-1$
				s.append(" -Djava.rmi.server.hostname="); //$NON-NLS-1$
				s.append(InetAddress.getLoopbackAddress().getHostAddress());
			}
			if (s.indexOf(" -Dorg.eclipse.statet.rj.rmi.disableSocketFactory=") < 0) {
				s.append(" -Dorg.eclipse.statet.rj.rmi.disableSocketFactory=true");
			}
			if (this.codebaseLibs != null && s.indexOf(" -Djava.rmi.server.codebase=") < 0) { //$NON-NLS-1$
				s.append(" -Djava.rmi.server.codebase=\""); //$NON-NLS-1$
				final List<BundleEntry> rjLibs= this.serverContext.resolveBundles(this.codebaseLibs);
				s.append(ServerUtils.concatCodebase(rjLibs));
				s.append("\""); //$NON-NLS-1$
			}
			
			if (!ToolRunner.captureLogOnly(configuration)
					&& s.indexOf(" -Dorg.eclipse.statet.rj.verbose=") < 0 ) { //$NON-NLS-1$
				s.append(" -Dorg.eclipse.statet.rj.verbose=true"); //$NON-NLS-1$
			}
			if (Platform.getOS().equals(Platform.OS_MACOSX)
					&& JavaRuntime.compareJavaVersions(JavaRuntime.computeVMInstall(configuration),
							JavaCore.VERSION_1_8) == 0
					&& s.indexOf(" -d32") < 0 && s.indexOf(" -d64") < 0) { //$NON-NLS-1$ //$NON-NLS-2$
				final String rArch= this.rEnvConfig.getRArch();
				if (rArch != null) {
					if (rArch.equals("i386") || rArch.equals("i586") || rArch.equals("i686")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						s.append(" -d32"); //$NON-NLS-1$
					}
					else if (rArch.equals("x86_64")) { //$NON-NLS-1$
						s.append(" -d64"); //$NON-NLS-1$
					}
				}
			}
			
			return s.substring(1);
		}
		catch (final StatusException e) {
			throw new CoreException(new Status(IStatus.ERROR, RConsoleUIPlugin.BUNDLE_ID,
					"An error occurred when configuring start of Java based R server.",
					EStatusUtils.convert(e) ));
		}
		catch (final RjException e) {
			throw new CoreException(new Status(IStatus.ERROR, RConsoleUIPlugin.BUNDLE_ID,
					"An error occurred when configuring start of Java based R server.",
					e ));
		}
	}
	
	@Override
	public String getMainTypeName(final ILaunchConfiguration configuration) throws CoreException {
		return "RJSrv"; //$NON-NLS-1$
	}
	
	@Override
	public String getProgramArguments(final ILaunchConfiguration configuration) throws CoreException {
		final StringBuilder args= new StringBuilder("start"); //$NON-NLS-1$
		args.append(' ');
		args.append(this.address);
		
		args.append(" -auth=none"); //$NON-NLS-1$
		
		args.append(" -plugins="); //$NON-NLS-1$
		args.append("awt,"); //$NON-NLS-1$
		if (Platform.getOS().equals(Platform.OS_WIN32)) { 
			args.append("swt,"); //$NON-NLS-1$
		}
		
		return args.toString();
	}
	
	@Override
	protected void prepareStopInMain(final ILaunchConfiguration configuration) throws CoreException {
	}
	
	
	public String getDebugInfo() {
		final ObjectUtils.ToStringBuilder sb= new ObjectUtils.ToStringBuilder();
		sb.addProp("R environment name", this.rEnvConfig.getName());
		sb.addProp("R package 'rj' path", this.rjPkgPath.toString());
		return sb.toString();
	}
	
}
