/*=============================================================================#
 # Copyright (c) 2008, 2021 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 static org.eclipse.statet.internal.r.console.ui.launching.RRemoteConsoleLaunchDelegate.DEFAULT_SSH_PORT;
import static org.eclipse.statet.nico.core.runtime.IToolEventHandler.LOGIN_SSH_HOST_DATA_KEY;
import static org.eclipse.statet.nico.core.runtime.IToolEventHandler.LOGIN_SSH_PORT_DATA_KEY;
import static org.eclipse.statet.nico.core.runtime.IToolEventHandler.LOGIN_USERNAME_DATA_KEY;
import static org.eclipse.statet.r.console.ui.launching.RConsoleLaunching.REMOTE_RJS;
import static org.eclipse.statet.r.console.ui.launching.RConsoleLaunching.REMOTE_RJS_RECONNECT;
import static org.eclipse.statet.r.console.ui.launching.RConsoleLaunching.REMOTE_RJS_SSH;

import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.rmi.server.RMIClientSocketFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.databinding.validation.MultiValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.variables.IStringVariable;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.StringVariableSelectionDialog;
import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

import com.jcraft.jsch.Session;

import org.eclipse.statet.jcommons.rmi.RMIAddress;

import org.eclipse.statet.ecommons.databinding.core.validation.IntegerValidator;
import org.eclipse.statet.ecommons.ui.components.WidgetToolsButton;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.r.console.ui.launching.RRemoteConsoleSelectionDialog.SpecialAddress;
import org.eclipse.statet.r.console.ui.IRConsoleHelpContextIds;
import org.eclipse.statet.r.console.ui.launching.RConsoleLaunching;
import org.eclipse.statet.r.nico.impl.RjsUtil;


public class RRemoteConsoleMainTab extends RConsoleMainTab {
	
	
	private class UpdateJob extends Job implements IValueChangeListener<Object> {
		
		private String user;
		private String address;
		private Integer sshPort;
		
		public UpdateJob() {
			super("Background Update for RRemoteConsoleMainTab");
			setSystem(true);
			setPriority(SHORT);
		}
		
		@Override
		protected IStatus run(final IProgressMonitor monitor) {
			final StringBuilder sb= new StringBuilder();
			sb.setLength(0);
			sb.append(this.user);
			sb.append('@');
			if (monitor.isCanceled()) {
				return Status.CANCEL_STATUS;
			}
			try {
				final RMIAddress rmiAddress= new RMIAddress(this.address);
				sb.append(rmiAddress.getHostAddress().getHostAddress());
			}
			catch (final UnknownHostException e) {
				sb.append("<unknown>");
			}
			catch (final Exception e) {
			}
			if (monitor.isCanceled()) {
				return Status.CANCEL_STATUS;
			}
			final Integer port= this.sshPort;
			if (port != null && port.intValue() != DEFAULT_SSH_PORT) {
				sb.append(':');
				sb.append(port.toString());
			}
			final String s= sb.toString();
			if (monitor.isCanceled()) {
				return Status.CANCEL_STATUS;
			}
			RRemoteConsoleMainTab.this.sshAddressValue.getRealm().asyncExec(new Runnable() {
				@Override
				public void run() {
					RRemoteConsoleMainTab.this.sshAddressValue.setValue(s);
				}
			});
			return Status.OK_STATUS;
		}
		
		@Override
		public void handleValueChange(final ValueChangeEvent<?> event) {
			cancel();
			this.user= RRemoteConsoleMainTab.this.userValue.getValue();
			this.address= RRemoteConsoleMainTab.this.addressValue.getValue();
			this.sshPort= RRemoteConsoleMainTab.this.sshPortValue.getValue();
			schedule(100);
		}
		
	}
	
	
	private final IObservableValue<String> addressValue;
	private final IObservableValue<String> userValue;
	private final IObservableValue<Integer> sshPortValue;
	private final IObservableValue<Boolean> sshTunnelValue;
	private final IObservableValue<String> commandValue;
	private final IObservableValue<String> sshAddressValue;
	
	private Text addressControl;
	private List<Control> addressControls;
	private RRemoteConsoleSelectionDialog remoteEngineSelectionDialog;
	
	private Text usernameControl;
	private List <Control> loginControls;
	private Label usernameInfo;
	
	private Text sshPortControl;
	private Text sshAddress;
	private Button sshTunnelControl;
	private List<Control> sshControls;
	
	private Text commandControl;
	private List<Control> commandControls;
	
	private UpdateJob updateJob;
	
	
	public RRemoteConsoleMainTab() {
		final Realm realm= getRealm();
		this.addressValue= new WritableValue<>(realm, "", String.class); //$NON-NLS-1$
		this.userValue= new WritableValue<>(realm, "", String.class); //$NON-NLS-1$
		this.sshPortValue= new WritableValue<>(realm, null, Integer.class);
		this.sshTunnelValue= new WritableValue<>(realm, false, Boolean.TYPE);
		this.commandValue= new WritableValue<>(realm, "", String.class); //$NON-NLS-1$
		this.sshAddressValue= new WritableValue<>(realm, "", String.class); //$NON-NLS-1$
	}
	
	
	@Override
	protected RConsoleType[] loadTypes() {
		final List<RConsoleType> types= new ArrayList<>();
		types.add(new RConsoleType("RJ (RMI/JRI) - Manual", REMOTE_RJS, false, true, false));
		types.add(new RConsoleType("RJ (RMI/JRI) - Start over SSH", REMOTE_RJS_SSH, false, true, false));
		types.add(new RConsoleType("RJ (RMI/JRI) - Quick Reconnect", REMOTE_RJS_RECONNECT, false, true, false));
		return types.toArray(new RConsoleType[types.size()]);
	}
	
	@Override
	public void createControl(final Composite parent) {
		this.updateJob= new UpdateJob();
		super.createControl(parent);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
				IRConsoleHelpContextIds.R_REMOTE_CONSOLE_LAUNCH);
	}
	
	@Override
	public void dispose() {
		super.dispose();
		if (this.updateJob != null) {
			this.updateJob.cancel();
			this.updateJob= null;
		}
	}
	
	@Override
	protected Composite createTypeDetailGroup(final Composite parent) {
		final Group group= new Group(parent, SWT.NONE);
		group.setLayout(LayoutUtils.newGroupGrid(4));
		group.setText("Connection:");
		
		this.addressControls= new ArrayList<>(8);
		this.loginControls= new ArrayList<>(8);
		this.sshControls= new ArrayList<>(8);
		this.commandControls= new ArrayList<>(8);
		
		{	// Address:
			final Label label= new Label(group, SWT.NONE);
			label.setText("&Address: ");
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final Composite composite= new Composite(group, SWT.NONE);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
			composite.setLayout(LayoutUtils.newCompositeGrid(2));
			
			this.addressControl= new Text(composite, SWT.LEFT | SWT.BORDER);
			this.addressControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			
			final Button addressButton= new Button(composite, SWT.PUSH);
			addressButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			addressButton.setText("Browse...");
			addressButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(final SelectionEvent event) {
					final boolean newDialog= (RRemoteConsoleMainTab.this.remoteEngineSelectionDialog == null);
					if (newDialog) {
						RRemoteConsoleMainTab.this.remoteEngineSelectionDialog= new RRemoteConsoleSelectionDialog(getShell(), false);
					}
					else {
						RRemoteConsoleMainTab.this.remoteEngineSelectionDialog.clearAdditionaAddress(true);
					}
					String userName= RRemoteConsoleMainTab.this.userValue.getValue();
					if (userName != null && userName.isEmpty()) {
						userName= null;
					}
					final String text= RRemoteConsoleMainTab.this.addressControl.getText();
					if (text.length() > 0) {
						try {
							final RMIAddress rmiAddress= new RMIAddress(text);
							final StringBuilder sb= new StringBuilder();
							sb.append(rmiAddress.getHost());
							if (rmiAddress.getPort() != RMIAddress.DEFAULT_PORT) {
								sb.append(':').append(rmiAddress.getPort());
							}
							final String address= sb.toString();
							RRemoteConsoleMainTab.this.remoteEngineSelectionDialog.addAdditionalAddress(address, null);
							if (newDialog) {
								RRemoteConsoleMainTab.this.remoteEngineSelectionDialog.setInitialAddress(address);
							}
							
							if (RRemoteConsoleMainTab.this.sshTunnelControl.isEnabled() && RRemoteConsoleMainTab.this.sshTunnelControl.getSelection()
									&& userName != null) {
								final Map<String, Object> loginData= new HashMap<>();
								loginData.put(LOGIN_SSH_HOST_DATA_KEY, rmiAddress.getHost());
								final Object sshPort= RRemoteConsoleMainTab.this.sshPortValue.getValue();
								loginData.put(LOGIN_SSH_PORT_DATA_KEY, (sshPort instanceof Integer) ?
										((Integer) sshPort).intValue() : DEFAULT_SSH_PORT );
								loginData.put(LOGIN_USERNAME_DATA_KEY, userName);
								final SpecialAddress special= new SpecialAddress(
										rmiAddress, "127.0.0.1" ) {
									@Override
									public RMIClientSocketFactory getSocketFactory(
											final IProgressMonitor monitor) throws CoreException {
										final Session session= RjsUtil.getSession(loginData, monitor);
										return RjsUtil.createRMIOverSshClientSocketFactory(session);
									}
								};
								final String label= rmiAddress.getHost() + " through SSH tunnel";
								RRemoteConsoleMainTab.this.remoteEngineSelectionDialog.addAdditionalAddress(label, special);
								RRemoteConsoleMainTab.this.remoteEngineSelectionDialog.setInitialAddress(label);
							}
						}
						catch (final Exception e) {}
					}
					
					RRemoteConsoleMainTab.this.remoteEngineSelectionDialog.setUser(userName);
					
					if (RRemoteConsoleMainTab.this.remoteEngineSelectionDialog.open() == Dialog.OK) {
						final String result= (String) RRemoteConsoleMainTab.this.remoteEngineSelectionDialog.getFirstResult();
						RRemoteConsoleMainTab.this.addressValue.setValue(result);
					}
				}
			});
			
			this.addressControls.add(label);
			this.addressControls.add(composite);
		}
		{	// Username:
			{	final Label label= new Label(group, SWT.NONE);
				label.setText("&Username: ");
				label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
				
				final Composite composite= new Composite(group, SWT.NONE);
				composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
				composite.setLayout(LayoutUtils.newCompositeGrid(2));
				
				this.usernameControl= new Text(composite, SWT.LEFT | SWT.BORDER);
				final GridData gd= new GridData(SWT.FILL, SWT.CENTER, false, false);
				gd.widthHint= gd.minimumWidth= LayoutUtils.hintWidth(this.usernameControl, 20);
				this.usernameControl.setLayoutData(gd);
				
				this.usernameInfo= new Label(composite, SWT.LEFT);
				this.usernameInfo.setText("");
				this.usernameInfo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
				
				this.loginControls.add(label);
				this.loginControls.add(this.usernameControl);
				this.loginControls.add(this.usernameInfo);
			}
			{	final Label label= new Label(group, SWT.NONE);
				label.setText("&SSH Port: ");
				label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
				
				this.sshPortControl= new Text(group, SWT.LEFT | SWT.BORDER);
				final GridData gd= new GridData(SWT.LEFT, SWT.CENTER, true, false);
				gd.widthHint= LayoutUtils.hintWidth(this.sshPortControl, 6);
				this.sshPortControl.setLayoutData(gd);
				
				this.sshControls.add(label);
				this.sshControls.add(this.sshPortControl);
			}
		}
		{	// Ext SSH:
			{	final Label label= new Label(group, SWT.NONE);
				label.setText("SSH Options: ");
				label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
				
				this.sshTunnelControl= new Button(group, SWT.CHECK);
				this.sshTunnelControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
				this.sshTunnelControl.setText("&Tunnel connections to R engine through SSH");
				
				this.sshControls.add(label);
				this.sshControls.add(this.sshTunnelControl);
			}
			{	final Label label= new Label(group, SWT.LEFT);
				label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
				label.setText("SSH Address:");
				
				this.sshAddress= new Text(group, SWT.LEFT | SWT.BORDER);
				this.sshAddress.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
				this.sshAddress.setEditable(false);
				
				this.sshControls.add(label);
				this.sshControls.add(this.sshAddress);
			}
		}
		
		{	// Remote Command:
			final Label label= new Label(group, SWT.NONE);
			label.setText("Re&mote Command: ");
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final Composite composite= new Composite(group, SWT.NONE);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
			composite.setLayout(LayoutUtils.newCompositeGrid(2));
			
			this.commandControl= new Text(composite, SWT.LEFT | SWT.BORDER);
			this.commandControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
			final WidgetToolsButton toolsButton= new WidgetToolsButton(this.commandControl) {
				@Override
				protected void fillMenu(final Menu menu) {
					final MenuItem item= new MenuItem(menu, SWT.PUSH);
					item.setText("Insert &Variable...");
					item.addSelectionListener(new SelectionAdapter() {
						@Override
						public void widgetSelected(final SelectionEvent e) {
							final StringVariableSelectionDialog dialog= new StringVariableSelectionDialog(getShell()) {
								@Override
								public void setElements(final Object[] elements) {
									super.setElements(new IStringVariable[] {
											RRemoteConsoleLaunchDelegate.ADDRESS_VARIABLE,
											RRemoteConsoleLaunchDelegate.NAME_VARIABLE,
											RRemoteConsoleLaunchDelegate.WD_VARIABLE,
									});
								}
							};
							if (dialog.open() != Dialog.OK) {
								return;
							}
							final String variable= dialog.getVariableExpression();
							if (variable == null) {
								return;
							}
							RRemoteConsoleMainTab.this.commandControl.insert(variable);
							RRemoteConsoleMainTab.this.commandControl.setFocus();
						}
					});
				}
			};
			toolsButton.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
			
			this.commandControls.add(label);
			this.commandControls.add(this.commandControl);
			this.commandControls.add(toolsButton);
		}
		
		return group;
	}
	
	@Override
	protected void createFooter(final Composite composite) {
		final Link link= new Link(composite, SWT.NONE);
		link.setText("Global preferences: "
				+ "<a href=\"org.eclipse.statet.nico.preferencePages.ResourceMappings\">Folder Mapping</a>, "
				+ "<a href=\"org.eclipse.jsch.ui.SSHPreferences\">SSH2 Options (Key Management)</a>.");
		composite.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));
		link.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				final PreferenceDialog dialog= org.eclipse.ui.dialogs.PreferencesUtil.createPreferenceDialogOn(null, e.text, null, null);
				if (dialog != null) {
					dialog.open();
				}
			}
		});
		super.createFooter(composite);
	}
	
	@Override
	protected void addBindings(final DataBindingContext dbc, final Realm realm) {
		super.addBindings(dbc, realm);
		
		final MultiValidator validator= new MultiValidator() {
			@Override
			protected IStatus validate() {
				// Calculate the validation status
				if (!getType().getId().equals(REMOTE_RJS_RECONNECT)) {
					final String text= RRemoteConsoleMainTab.this.addressValue.getValue();
					if (text == null || text.isEmpty()) {
						return ValidationStatus.error("Missing address for R remote engine ('//host[:port]/rsessionname').");
					}
					try {
						RMIAddress.validate(text);
					}
					catch (final MalformedURLException e) {
						return ValidationStatus.error("Invalid address for R remote engine: "+e.getLocalizedMessage());
					}
				}
				return ValidationStatus.ok();
			}
		};
		
		final WritableValue<String> addressValue1= new WritableValue<>("", String.class); //$NON-NLS-1$
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify)
						.observe(this.addressControl),
				addressValue1 );
		validator.observeValidatedValue(addressValue1);
		dbc.bindValue(
				addressValue1,
				this.addressValue );
		
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify)
						.observe(this.usernameControl),
				this.userValue );
		
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify)
						.observe(this.sshPortControl),
				this.sshPortValue,
				new UpdateValueStrategy<String, Integer>()
						.setAfterGetValidator(new IntegerValidator(0, 65535, true,
								"Invalid SSH port number specified (0-65535)." )),
				null );
		dbc.bindValue(
				WidgetProperties.buttonSelection()
						.observe(this.sshTunnelControl),
				this.sshTunnelValue );
		
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify)
						.observe(this.commandControl),
				this.commandValue );
		
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify)
						.observe(this.sshAddress),
				this.sshAddressValue );
		
		this.addressValue.addValueChangeListener(this.updateJob);
		this.userValue.addValueChangeListener(this.updateJob);
		this.sshPortValue.addValueChangeListener(this.updateJob);
		
		dbc.addValidationStatusProvider(validator);
		validator.observeValidatedValue(getTypeValue());
	}
	
	@Override
	protected void updateType(final RConsoleType type) {
		if (REMOTE_RJS.equals(type.getId())) {
			DialogUtils.setEnabled(this.addressControls, null, true);
			DialogUtils.setEnabled(getArgumentComposite(), null, true);
			DialogUtils.setEnabled(this.loginControls, null, true);
			this.usernameInfo.setText("(optional)");
			DialogUtils.setVisible(this.sshControls, null, true);
			DialogUtils.setVisible(this.commandControls, null, false);
		}
		else if (REMOTE_RJS_SSH.equals(type.getId())) {
			DialogUtils.setEnabled(this.addressControls, null, true);
			DialogUtils.setEnabled(getArgumentComposite(), null, true);
			DialogUtils.setEnabled(this.loginControls, null, true);
			this.usernameInfo.setText("(required)");
			DialogUtils.setVisible(this.sshControls, null, true);
			DialogUtils.setVisible(this.commandControls, null, true);
			
			UIAccess.getDisplay().asyncExec(new Runnable() {
				@Override
				public void run() {
					if (RRemoteConsoleMainTab.this.userValue.getValue() == null || RRemoteConsoleMainTab.this.userValue.getValue().isEmpty()) {
						RRemoteConsoleMainTab.this.userValue.setValue(System.getProperty("user.name")); 
					}
					if (RRemoteConsoleMainTab.this.sshPortValue.getValue() == null) {
						RRemoteConsoleMainTab.this.sshPortValue.setValue(22);
					}
					if (RRemoteConsoleMainTab.this.commandValue.getValue() == null || RRemoteConsoleMainTab.this.commandValue.getValue().isEmpty()) {
						RRemoteConsoleMainTab.this.commandValue.setValue(RRemoteConsoleLaunchDelegate.DEFAULT_COMMAND);
					}
				}
			});
		}
		else {
			DialogUtils.setEnabled(this.addressControls, null, false);
			DialogUtils.setEnabled(getArgumentComposite(), null, false);
			DialogUtils.setEnabled(this.loginControls, null, true);
			this.usernameInfo.setText("");
			DialogUtils.setVisible(this.sshControls, null, false);
			DialogUtils.setVisible(this.commandControls, null, false);
		}
	}
	
	
	@Override
	public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) {
		super.setDefaults(configuration);
		configuration.setAttribute(RConsoleLaunching.ATTR_ADDRESS, "//host/rsessionname"); //$NON-NLS-1$
	}
	
	@Override
	protected void doInitialize(final ILaunchConfiguration configuration) {
		super.doInitialize(configuration);
		
		this.addressValue.setValue(readAttribute(configuration,
				RConsoleLaunching.ATTR_ADDRESS,
				"" )); //$NON-NLS-1$
		
		this.userValue.setValue(readAttribute(configuration,
				RConsoleLaunching.ATTR_LOGIN_NAME,
				"" )); //$NON-NLS-1$
		
		this.sshPortValue.setValue(readAttribute(configuration,
				RConsoleLaunching.ATTR_SSH_PORT,
				DEFAULT_SSH_PORT ));
		
		this.sshTunnelValue.setValue(readAttribute(configuration,
				RConsoleLaunching.ATTR_SSH_TUNNEL_ENABLED,
				false ));
		
		this.commandValue.setValue(readAttribute(configuration,
				RConsoleLaunching.ATTR_COMMAND,
				"" ));
	}
	
	@Override
	protected void doSave(final ILaunchConfigurationWorkingCopy configuration) {
		super.doSave(configuration);
		
		if (this.addressControl.isEnabled()) {
			configuration.setAttribute(RConsoleLaunching.ATTR_ADDRESS, this.addressValue.getValue());
		}
		else {
			configuration.removeAttribute(RConsoleLaunching.ATTR_ADDRESS);
		}
		
		final String user= this.userValue.getValue();
		if (user != null && user.length() > 0) {
			configuration.setAttribute(RConsoleLaunching.ATTR_LOGIN_NAME, user);
		}
		else {
			configuration.removeAttribute(RConsoleLaunching.ATTR_LOGIN_NAME);
		}
		
		final Integer port= this.sshPortValue.getValue();
		if (!getType().getId().equals(REMOTE_RJS_RECONNECT) && port != null) {
			configuration.setAttribute(RConsoleLaunching.ATTR_SSH_PORT, port.intValue());
		}
		else {
			configuration.removeAttribute(RConsoleLaunching.ATTR_SSH_PORT);
		}
		
		final Boolean tunnel= this.sshTunnelValue.getValue();
		if (!getType().getId().equals(REMOTE_RJS_RECONNECT) && tunnel != null) {
			configuration.setAttribute(RConsoleLaunching.ATTR_SSH_TUNNEL_ENABLED, tunnel.booleanValue());
		}
		else {
			configuration.removeAttribute(RConsoleLaunching.ATTR_SSH_TUNNEL_ENABLED);
		}
		
		final String command= this.commandValue.getValue();
		if (getType().getId().equals(REMOTE_RJS_SSH) && command != null) {
			configuration.setAttribute(RConsoleLaunching.ATTR_COMMAND, command);
		}
		else {
			configuration.removeAttribute(RConsoleLaunching.ATTR_COMMAND);
		}
	}
	
}
