/*=============================================================================#
 # Copyright (c) 2007, 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.internal.r.debug.ui.preferences;

import static org.eclipse.statet.rj.renv.core.REnvConfiguration.R_HOME_DIRECTORY_VAR_STRING;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import com.ibm.icu.text.Collator;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
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.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.osgi.util.NLS;
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.Combo;
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.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.StatusException;

import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.debug.core.util.LaunchUtils;
import org.eclipse.statet.ecommons.debug.ui.util.ProcessOutputCollector;
import org.eclipse.statet.ecommons.io.FileUtil;
import org.eclipse.statet.ecommons.runtime.core.util.StatusUtils;
import org.eclipse.statet.ecommons.ui.components.ButtonGroup;
import org.eclipse.statet.ecommons.ui.components.DataAdapter;
import org.eclipse.statet.ecommons.ui.components.ExtensibleTextCellEditor;
import org.eclipse.statet.ecommons.ui.dialogs.ExtStatusDialog;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.MessageUtils;
import org.eclipse.statet.ecommons.ui.util.VariableFilterUtils;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils.TreeComposite;
import org.eclipse.statet.ecommons.ui.workbench.ResourceInputComposite;

import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.internal.r.ui.help.IRUIHelpContextIds;
import org.eclipse.statet.r.core.RUtil;
import org.eclipse.statet.r.core.renv.IREnvConfiguration;
import org.eclipse.statet.r.core.renv.IREnvConfiguration.Exec;
import org.eclipse.statet.r.core.renv.RLibGroupWorkingCopy;
import org.eclipse.statet.r.ui.REnvLabelProvider;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.rj.renv.core.BasicREnvConfiguration;
import org.eclipse.statet.rj.renv.core.DefaultLocalConfigurator;
import org.eclipse.statet.rj.renv.core.RLibGroup;
import org.eclipse.statet.rj.renv.core.RLibLocation;


/**
 * Dialog for a local standard {@link IREnvConfiguration} (<code>user-local</code>)
 */
public class LocalREnvConfigDialog extends ExtStatusDialog {
	
	
	private static final String DETECT_START= "_R-Path-And-Library-Configuration_"; //$NON-NLS-1$
	private static final String DETECT_COMMAND= "cat('"+DETECT_START+"'," //$NON-NLS-1$ //$NON-NLS-2$
			+ "Sys.getenv(\'R_HOME\')," //$NON-NLS-1$
			+ "Sys.getenv(\'R_ARCH\')," //$NON-NLS-1$
			+ "paste(.Library,collapse=.Platform$path.sep)," //$NON-NLS-1$
			+ "paste(.Library.site,collapse=.Platform$path.sep)," //$NON-NLS-1$
			+ "Sys.getenv('R_LIBS')," //$NON-NLS-1$
			+ "Sys.getenv('R_LIBS_USER')," //$NON-NLS-1$
			+ "R.home('doc')," //$NON-NLS-1$
			+ "R.home('share')," //$NON-NLS-1$
			+ "R.home('include')," //$NON-NLS-1$
			+ "R.version$arch," //$NON-NLS-1$
			+ ".Platform$OS.type," //$NON-NLS-1$
			+ "sep=intToUtf8(0x0AL));"; //$NON-NLS-1$
	
	private static final int DETECT_LENGTH= 12;
	private static final int DETECT_R_HOME= 1;
	private static final int DETECT_R_ARCHVAR= 2;
	private static final int DETECT_R_DEFAULT= 3;
	private static final int DETECT_R_SITE= 4;
	private static final int DETECT_R_OTHER= 5;
	private static final int DETECT_R_USER= 6;
	private static final int DETECT_R_DOC_DIR= 7;
	private static final int DETECT_R_SHARE_DIR= 8;
	private static final int DETECT_R_INCLUDE_DIR= 9;
	private static final int DETECT_R_ARCH= 10;
	private static final int DETECT_R_OS= 11;
	private static final Pattern DETECT_ITEM_PATTERN= RUtil.LINE_SEPARATOR_PATTERN;
	private static final Pattern DETECT_PATH_PATTERN= Pattern.compile(File.pathSeparator, Pattern.LITERAL);
	
	
	private class RHomeComposite extends ResourceInputComposite {
		
		public RHomeComposite(final Composite parent) {
			super (parent, 
					ResourceInputComposite.STYLE_TEXT,
					ResourceInputComposite.MODE_DIRECTORY | ResourceInputComposite.MODE_OPEN, 
					Messages.REnv_Detail_Location_label);
			setShowInsertVariable(true, VariableFilterUtils.DEFAULT_NON_ITERACTIVE_FILTERS, null);
		}
		
		@Override
		protected void fillMenu(final Menu menu) {
			super.fillMenu(menu);
			
			final MenuItem item= new MenuItem(menu, SWT.PUSH);
			item.setText(Messages.REnv_Detail_Location_FindAuto_label);
			item.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(final SelectionEvent e) {
					final String[] rhome= searchRHOME();
					if (rhome != null) {
						setText(rhome[0]);
						updateArchs(false);
						final String current= LocalREnvConfigDialog.this.nameControl.getText().trim();
						if ((current.isEmpty() || current.equals("R")) && rhome[1] != null) { //$NON-NLS-1$
							LocalREnvConfigDialog.this.nameControl.setText(rhome[1]);
						}
					}
					else {
						final String name= Messages.REnv_Detail_Location_label;
						MessageDialog.openInformation(getShell(), 
								MessageUtils.removeMnemonics(name), 
								NLS.bind(Messages.REnv_Detail_Location_FindAuto_Failed_message, name));
					}
					getTextControl().setFocus();
				}
			});
			
		}
		
	}
	
	private static class RLibraryContainer {
		
		
		private final RLibGroupWorkingCopy parent;
		
		private RLibLocation library;
		
		
		RLibraryContainer(final RLibGroupWorkingCopy parent, final RLibLocation library) {
			this.parent= parent;
			this.library= library;
		}
		
		
		public boolean set(final String directory) {
			if (!this.library.getDirectory().equals(directory)) {
				this.library= this.parent.setLibrary(this.library, directory);
				return true;
			}
			return false;
		}
		
		
		@Override
		public int hashCode() {
			return this.library.hashCode();
		}
		
		@Override
		public boolean equals(final @Nullable Object obj) {
			if (this == obj) {
				return true;
			}
			if (obj instanceof RLibraryContainer) {
				final RLibraryContainer other= (RLibraryContainer) obj;
				return (this.library == other.library);
			}
			return false;
		}
	}
	
	
	private final IREnvConfiguration.WorkingCopy configModel;
	private final boolean isNewConfig;
	private final Set<String> existingNames;
	
	private Text nameControl;
	private ResourceInputComposite rHomeControl;
	
	private Button loadButton;
	
	private Combo rArchControl;
	
	private TreeViewer rLibrariesViewer;
	private ButtonGroup<RLibLocation> rLibrariesButtons;
	
	private ResourceInputComposite rDocDirectoryControl;
	private ResourceInputComposite rShareDirectoryControl;
	private ResourceInputComposite rIncludeDirectoryControl;
	
	
	public LocalREnvConfigDialog(final Shell parent, 
			final IREnvConfiguration.WorkingCopy config, final boolean isNewConfig, 
			final Collection<IREnvConfiguration> existingConfigs) {
		super(parent, WITH_RUNNABLE_CONTEXT | ((isNewConfig) ? WITH_DATABINDING_CONTEXT :
			(WITH_DATABINDING_CONTEXT | SHOW_INITIAL_STATUS)) );
		
		this.configModel= config;
		this.isNewConfig= isNewConfig;
		this.existingNames= new HashSet<>();
		for (final IREnvConfiguration ec : existingConfigs) {
			this.existingNames.add(ec.getName());
		}
		setTitle(this.isNewConfig ?
				Messages.REnv_Detail_AddDialog_title : 
				Messages.REnv_Detail_Edit_Dialog_title );
	}
	
	
	@Override
	public void create() {
		super.create();
		
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), IRUIHelpContextIds.R_ENV);
	}
	
	@Override
	protected Control createDialogArea(final Composite parent) {
		final Composite area= new Composite(parent, SWT.NONE);
		area.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		area.setLayout(LayoutUtils.newDialogGrid(2));
		
		{	// Name:
			final Label label= new Label(area, SWT.LEFT);
			label.setText(Messages.REnv_Detail_Name_label+':');
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			this.nameControl= new Text(area, SWT.BORDER);
			final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false);
			gd.widthHint= LayoutUtils.hintWidth(this.nameControl, 60);
			this.nameControl.setLayoutData(gd);
			this.nameControl.setEditable(this.configModel.isEditable());
		}
		
		if (this.configModel.isEditable()) {
			// Location:
			final Label label= new Label(area, SWT.LEFT);
			label.setText(Messages.REnv_Detail_Location_label+':');
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			this.rHomeControl= new RHomeComposite(area);
			this.rHomeControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		}
		
		LayoutUtils.addSmallFiller(area, false);
		
		{	// Architecture / Bits:
			final Label label= new Label(area, SWT.LEFT);
			label.setText(Messages.REnv_Detail_Arch_label+':');
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final Composite composite= new Composite(area, SWT.NONE);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			composite.setLayout(LayoutUtils.newCompositeGrid(3));
			
			{	this.rArchControl= new Combo(composite, SWT.DROP_DOWN);
				final GridData gd= new GridData(SWT.FILL, SWT.FILL, false, false);
				gd.widthHint= LayoutUtils.hintWidth(this.rArchControl, 8);
				this.rArchControl.setLayoutData(gd);
				this.rArchControl.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(final SelectionEvent e) {
						final int selectionIdx;
						if (!LocalREnvConfigDialog.this.rArchControl.getListVisible()
								&& (selectionIdx= LocalREnvConfigDialog.this.rArchControl.getSelectionIndex()) >= 0) {
							final String item= LocalREnvConfigDialog.this.rArchControl.getItem(selectionIdx);
						}
					}
				});
				this.rArchControl.setEnabled(this.configModel.isEditable());
			}
			
			if (this.configModel.isEditable()) {
				this.loadButton= new Button(composite, SWT.PUSH);
				this.loadButton.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, false, 2, 1));
				this.loadButton.setText(Messages.REnv_Detail_DetectSettings_label);
				this.loadButton.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(final SelectionEvent e) {
						detectSettings();
					}
				});
			}
			else {
				LayoutUtils.addGDDummy(composite, true, 2);
			}
		}
		
		{	// Libraries:
			final Label label= new Label(area, SWT.LEFT);
			label.setText(Messages.REnv_Detail_Libraries_label+":"); //$NON-NLS-1$
			label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
			
			final Composite composite= new Composite(area, SWT.NONE);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
			composite.setLayout(LayoutUtils.newCompositeGrid(2));
			
			final TreeComposite treeComposite= new ViewerUtils.TreeComposite(composite, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
			this.rLibrariesViewer= treeComposite.viewer;
			final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true);
			gd.widthHint= LayoutUtils.hintWidth(this.nameControl, 80);
			gd.heightHint= LayoutUtils.hintHeight(treeComposite.tree, 10);
			treeComposite.setLayoutData(gd);
			treeComposite.viewer.setContentProvider(new ITreeContentProvider() {
				@Override
				public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
				}
				@Override
				public void dispose() {
				}
				@Override
				public Object[] getElements(final Object inputElement) {
					return LocalREnvConfigDialog.this.configModel.getRLibGroups().toArray();
				}
				@Override
				public Object getParent(final Object element) {
					if (element instanceof RLibraryContainer) {
						return ((RLibraryContainer) element).parent;
					}
					return null;
				}
				@Override
				public boolean hasChildren(final Object element) {
					if (element instanceof RLibGroupWorkingCopy) {
						return !((RLibGroupWorkingCopy) element).getLibLocations().isEmpty();
					}
					return false;
				}
				@Override
				public Object[] getChildren(final Object parentElement) {
					if (parentElement instanceof RLibGroupWorkingCopy) {
						final RLibGroupWorkingCopy group= (RLibGroupWorkingCopy) parentElement;
						final List<? extends RLibLocation> libs= group.getLibLocations();
						final RLibraryContainer[] array= new RLibraryContainer[libs.size()];
						for (int i= 0; i < libs.size(); i++) {
							array[i]= new RLibraryContainer(group, libs.get(i));
						}
						return array;
					}
					return null;
				}
			});
			final TreeViewerColumn column= treeComposite.addColumn(SWT.LEFT, new ColumnWeightData(100));
			column.setLabelProvider(new REnvLabelProvider() {
				@Override
				public void update(final ViewerCell cell) {
					final Object element= cell.getElement();
					if (element instanceof RLibraryContainer) {
						final RLibLocation lib= ((RLibraryContainer) element).library;
						cell.setImage(RUI.getImage(RUI.IMG_OBJ_LIBRARY_LOCATION));
						if (lib.getSource() != RLibLocation.USER && lib.getLabel() != null) {
							cell.setText(lib.getLabel());
						}
						else {
							cell.setText(lib.getDirectory());
						}
						finishUpdate(cell);
						return;
					}
					super.update(cell);
				}
			});
			column.setEditingSupport(new EditingSupport(treeComposite.viewer) {
				@Override
				protected boolean canEdit(final Object element) {
					if (element instanceof RLibraryContainer) {
						final RLibraryContainer container= ((RLibraryContainer) element);
						return (container.library.getSource() == RLibLocation.USER);
					}
					return false;
				}
				@Override
				protected void setValue(final Object element, final Object value) {
					final RLibraryContainer container= (RLibraryContainer) element;
					if (container.set((String) value)) {
						getViewer().refresh(container, true);
						getDataBinding().updateStatus();
					}
				}
				@Override
				protected Object getValue(final Object element) {
					final RLibraryContainer container= (RLibraryContainer) element;
					return container.library.getDirectory();
				}
				@Override
				protected CellEditor getCellEditor(final Object element) {
					return new ExtensibleTextCellEditor(treeComposite.tree) {
						@Override
						protected Control createCustomControl(final Composite parent) {
							final ResourceInputComposite chooseResourceComposite= new ResourceInputComposite(parent,
									ResourceInputComposite.STYLE_TEXT,
									ResourceInputComposite.MODE_DIRECTORY | ResourceInputComposite.MODE_OPEN,
									Messages.REnv_Detail_LibraryLocation_label) {
								@Override
								protected void beforeMenuAction() {
									getFocusGroup().discontinueTracking();
								}
								@Override
								protected void afterMenuAction() {
									getFocusGroup().continueTracking();
								}
							};
							chooseResourceComposite.setShowInsertVariable(true,
									VariableFilterUtils.DEFAULT_NON_ITERACTIVE_FILTERS, null);
							this.text= (Text) chooseResourceComposite.getTextControl();
							return chooseResourceComposite;
						}
					};
				}
			});
			treeComposite.viewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
			treeComposite.viewer.setInput(this.configModel);
			ViewerUtils.installDefaultEditBehaviour(treeComposite.viewer);
			ViewerUtils.scheduleStandardSelection(treeComposite.viewer);
			
			this.rLibrariesButtons= new ButtonGroup<RLibLocation>(composite) {
				@Override
				protected RLibLocation edit1(final RLibLocation item, final boolean newItem, final Object parent) {
					if (newItem) {
						return ((RLibGroupWorkingCopy) parent).newLibrary(""); //$NON-NLS-1$
					}
					return item;
				}
				@Override
				public void updateState() {
					super.updateState();
					if (getDataAdapter().isDirty()) {
						getDataBinding().updateStatus();
					}
				}
			};
			this.rLibrariesButtons.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
			this.rLibrariesButtons.addAddButton(null);
			this.rLibrariesButtons.addDeleteButton(null);
//			this.rLibrariesButtons.addSeparator();
//			this.rLibrariesButtons.addUpButton();
//			this.rLibrariesButtons.addDownButton();
			
			final DataAdapter<RLibLocation> adapter= new DataAdapter.TreeAdapter<RLibLocation>(
					(ITreeContentProvider) this.rLibrariesViewer.getContentProvider(), null ) {
				private RLibGroupWorkingCopy getGroup(final Object element) {
					if (element instanceof RLibGroupWorkingCopy) {
						return (RLibGroupWorkingCopy) element;
					}
					else {
						return ((RLibraryContainer) element).parent;
					}
				}
				@Override
				public RLibLocation getModelItem(final Object element) {
					if (element instanceof RLibraryContainer) {
						return ((RLibraryContainer) element).library;
					}
					return (RLibLocation) element;
				}
				@Override
				public Object getViewerElement(final RLibLocation item, final Object parent) {
					return new RLibraryContainer((RLibGroupWorkingCopy) parent, item);
				}
				@Override
				public boolean isAddAllowed(final Object element) {
					return !getGroup(element).getId().equals(RLibGroup.R_DEFAULT);
				}
				@Override
				public boolean isModifyAllowed(final Object element) {
					return ( element instanceof RLibraryContainer
							&& ((RLibraryContainer) element).library.getSource() == RLibLocation.USER );
				}
				@Override
				public Object getAddParent(final Object element) {
					return getGroup(element);
				}
				@Override
				public List<? extends RLibLocation> getContainerFor(final Object element) {
					if (element instanceof RLibGroup) {
						return ((RLibGroup) element).getLibLocations();
					}
					else {
						return ((RLibraryContainer) element).parent.getLibLocations();
					}
				}
			};
			this.rLibrariesButtons.connectTo(this.rLibrariesViewer, adapter);
		}
		
		if (this.configModel.isEditable()) {
			final Composite group= createInstallDirGroup(area);
			if (group != null) {
				group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
			}
		}
		
		LayoutUtils.addSmallFiller(area, true);
		
		applyDialogFont(area);
		
		return area;
	}
	
	private Composite createInstallDirGroup(final Composite parent) {
		final Group composite= new Group(parent, SWT.NONE);
		composite.setLayout(LayoutUtils.newGroupGrid(2));
		composite.setText("Advanced - Installation locations:");
		{	final Label label= new Label(composite, SWT.NONE);
			label.setText("Documentation ('R_DOC_DIR'):");
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final ResourceInputComposite text= new ResourceInputComposite(composite, ResourceInputComposite.STYLE_TEXT,
					(ResourceInputComposite.MODE_DIRECTORY | ResourceInputComposite.MODE_OPEN), "R_DOC_DIR"); //$NON-NLS-1$
			text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			text.setShowInsertVariable(true, VariableFilterUtils.DEFAULT_NON_ITERACTIVE_FILTERS, null);
			this.rDocDirectoryControl= text;
		}
		{	final Label label= new Label(composite, SWT.NONE);
			label.setText("Shared files ('R_SHARE_DIR'):");
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final ResourceInputComposite text= new ResourceInputComposite(composite, ResourceInputComposite.STYLE_TEXT,
					(ResourceInputComposite.MODE_DIRECTORY | ResourceInputComposite.MODE_OPEN), "R_SHARE_DIR"); //$NON-NLS-1$
			text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			text.setShowInsertVariable(true, VariableFilterUtils.DEFAULT_NON_ITERACTIVE_FILTERS, null);
			this.rShareDirectoryControl= text;
		}
		{	final Label label= new Label(composite, SWT.NONE);
			label.setText("Include files ('R_INCLUDE_DIR'):");
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final ResourceInputComposite text= new ResourceInputComposite(composite, ResourceInputComposite.STYLE_TEXT,
					(ResourceInputComposite.MODE_DIRECTORY | ResourceInputComposite.MODE_OPEN), "R_INCLUDE_DIR"); //$NON-NLS-1$
			text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			text.setShowInsertVariable(true, VariableFilterUtils.DEFAULT_NON_ITERACTIVE_FILTERS, null);
			this.rIncludeDirectoryControl= text;
		}
		return composite;
	}
	
	@Override
	protected void addBindings(final DataBindingSupport db) {
		// don't specify IREnvConfiguration.WorkingCopy for BeanProperties (missing with getter)
		db.getContext().bindValue(
				WidgetProperties.text(SWT.Modify).observe(this.nameControl),
				BeanProperties.value(IREnvConfiguration.PROP_NAME, String.class)
						.observe(this.configModel),
				new UpdateValueStrategy().setAfterGetValidator(
						(final Object value) -> {
							String s= (String) value;
							s= s.trim();
							if (s.isEmpty()) {
								return ValidationStatus.error(Messages.REnv_Detail_Name_error_Missing_message);
							}
							if (LocalREnvConfigDialog.this.existingNames.contains(s)) {
								return ValidationStatus.error(Messages.REnv_Detail_Name_error_Duplicate_message);
							}
							if (s.contains("/")) {  //$NON-NLS-1$
								return ValidationStatus.error(Messages.REnv_Detail_Name_error_InvalidChar_message);
							}
							return ValidationStatus.ok();
						} ),
				null );
		if (this.rHomeControl != null) {
			final Binding rHomeBinding= db.getContext().bindValue(
					this.rHomeControl.getObservable(),
					BeanProperties.value(IREnvConfiguration.PROP_RHOME, String.class)
							.observe(this.configModel),
					new UpdateValueStrategy().setAfterGetValidator(
							(final Object value) -> {
								final IStatus status= LocalREnvConfigDialog.this.rHomeControl.getValidator().validate(value);
								if (!status.isOK()) {
									return status;
								}
								if (!LocalREnvConfigDialog.this.configModel.isValidRHomeLocation(LocalREnvConfigDialog.this.rHomeControl.getResourceAsFileStore())) {
									return ValidationStatus.error(Messages.REnv_Detail_Location_error_NoRHome_message);
								}
								updateArchs(!LocalREnvConfigDialog.this.isNewConfig);
								return ValidationStatus.ok();
							} ),
					null );
			rHomeBinding.getValidationStatus().addValueChangeListener(
					(final ValueChangeEvent<? extends IStatus> event) -> {
						final IStatus status= event.diff.getNewValue();
						LocalREnvConfigDialog.this.loadButton.setEnabled(status.isOK());
					} );
			rHomeBinding.validateTargetToModel();
		}
		db.getContext().bindValue(
				WidgetProperties.text().observe(this.rArchControl),
				BeanProperties.value(IREnvConfiguration.PROP_SUBARCH, String.class)
						.observe(this.configModel) );
		
		if (this.rDocDirectoryControl != null) {
			db.getContext().bindValue(
					this.rDocDirectoryControl.getObservable(),
					BeanProperties.value(IREnvConfiguration.PROP_RDOC_DIRECTORY, String.class)
							.observe(this.configModel) );
			db.getContext().bindValue(
					this.rShareDirectoryControl.getObservable(),
					BeanProperties.value(IREnvConfiguration.PROP_RSHARE_DIRECTORY, String.class)
							.observe(this.configModel) );
			db.getContext().bindValue(
					this.rIncludeDirectoryControl.getObservable(),
					BeanProperties.value(IREnvConfiguration.PROP_RINCLUDE_DIRECTORY, String.class)
							.observe(this.configModel) );
		}
	}
	
	private String[] searchRHOME() {
		try {
			final IStringVariableManager variables= VariablesPlugin.getDefault().getStringVariableManager();
			
			{	String loc= variables.performStringSubstitution("${env_var:R_HOME}", false); //$NON-NLS-1$
				if (loc != null && loc.length() > 0) {
					loc= resolve(loc);
					if (loc != null) {
						final IFileStore locStore= EFS.getLocalFileSystem().getStore(new Path(loc));
						if (locStore.fetchInfo().exists()) {
							return new String[] { loc, Messages.REnv_SystemRHome_name };
						}
					}
				}
			}
			
			final ImList<String> locCandidates;
			String prefixPattern= null;
			String prefixReplacement= null;
			if (Platform.getOS().startsWith("win")) { //$NON-NLS-1$
				String baseLoc= "${env_var:PROGRAMFILES}\\R";  //$NON-NLS-1$
				final IFileStore baseStore= EFS.getLocalFileSystem().getStore(
						new Path(variables.performStringSubstitution(baseLoc)));
				if (baseStore.fetchInfo().exists()) {
					prefixReplacement= baseLoc;
					prefixPattern= baseLoc= FileUtil.toString(baseStore);
					
					final String[] names= baseStore.childNames(EFS.NONE, null);
					Arrays.sort(names, 0, names.length,
							Collections.reverseOrder(Collator.getInstance()) );
					for (int i= 0; i < names.length; i++) {
						names[i]= baseLoc + '\\' + names[i];
					}
					locCandidates= ImCollections.newList(names);
				}
				else {
					locCandidates= ImCollections.newList();
				}
			}
			else if (Platform.getOS().equals(Platform.OS_MACOSX)) {
				locCandidates= ImCollections.newList(
						"/Library/Frameworks/R.framework/Resources" //$NON-NLS-1$
				);
			}
			else {
				locCandidates= ImCollections.newList(
						"/usr/local/lib64/R", //$NON-NLS-1$
						"/usr/lib64/R", //$NON-NLS-1$
						"/usr/local/lib/R", //$NON-NLS-1$
						"/usr/lib/R" //$NON-NLS-1$
				);
			}
			for (String loc : locCandidates) {
				loc= resolve(loc);
				if (loc != null) {
					final IFileStore locStore= EFS.getLocalFileSystem().getStore(new Path(loc));
					if (this.configModel.isValidRHomeLocation(locStore)) {
						if (prefixPattern != null && loc.startsWith(prefixPattern)) {
							loc= prefixReplacement + loc.substring(prefixPattern.length());
						}
						String name= locStore.getName();
						if (name.equals("Resources")) { //$NON-NLS-1$
							final IFileStore parent= locStore.getParent();
							name= (parent != null) ? parent.getName() : null;
						}
						if (name != null) {
							if (name.isEmpty() || name.equals("R")) { //$NON-NLS-1$
								name= null;
							}
							else if (Character.isDigit(name.charAt(0))) {
								name= "R " + name; //$NON-NLS-1$
							}
						}
						return new String[] { loc, name };
					}
				}
			}
			return null;
		}
		catch (final Exception e) {
			RUIPlugin.logError(-1, "Error when searching R_HOME location", e); //$NON-NLS-1$
			return null;
		}
	}
	
	private String resolve(final String loc) {
		try {
			java.nio.file.Path path= Paths.get(loc);
			path= path.toRealPath();
			return path.toString();
		}
		catch (final IOException e2) {
			return null;
		}
	}
	
	private void updateArchs(final boolean conservative) {
		if (this.rHomeControl == null) {
			return;
		}
		try {
			final IFileStore rHome= this.rHomeControl.getResourceAsFileStore();
			final List<String> availableArchs= this.configModel.searchAvailableSubArchs(rHome);
			if (availableArchs == null) {
				this.rArchControl.setItems(new String[0]);
				return;
			}
			final String oldArch= this.rArchControl.getText();
			this.rArchControl.setItems(availableArchs.toArray(new String[availableArchs.size()]));
			int idx= (oldArch.length() > 0) ? availableArchs.indexOf(oldArch) : -1;
			if (idx >= 0) {
				this.rArchControl.select(idx);
			}
			
			if (conservative && this.rArchControl.getText().length() > 0) {
				return;
			}
			idx= availableArchs.indexOf(Platform.getOSArch());
			if (idx < 0) {
				if (Platform.getOSArch().equals(Platform.ARCH_X86)) {
					idx= availableArchs.indexOf("i386"); //$NON-NLS-1$
					if (idx < 0) {
						idx= availableArchs.indexOf("i586"); //$NON-NLS-1$
						if (idx < 0) {
							idx= availableArchs.indexOf("i686"); //$NON-NLS-1$
						}
					}
				}
			}
			if (idx < 0) {
				idx= 0;
			}
			this.rArchControl.select(idx);
		}
		catch (final Exception e) {
			this.rArchControl.setItems(new String[0]);
		}
	}
	
	private void detectSettings() {
		try {
			run(true, true, new IRunnableWithProgress() {
				@Override
				public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					try {
						detectSettings(monitor);
					}
					catch (final CoreException e) {
						throw new InvocationTargetException(e);
					}
				}
			});
		}
		catch (final InvocationTargetException e) {
			final String message= (e.getCause() instanceof CoreException) ?
					Messages.REnv_Detail_DetectSettings_error_message :
					Messages.REnv_Detail_DetectSettings_error_Unexpected_message;
			StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, -1,
					message, e), StatusManager.LOG);
			StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, -1,
					message, e.getCause()), StatusManager.SHOW);
		}
		catch (final InterruptedException e) {
		}
		this.rLibrariesButtons.refresh();
		this.rLibrariesViewer.expandAll();
	}
	
	private void detectSettings(final IProgressMonitor monitor) throws CoreException {
		monitor.beginTask(Messages.REnv_Detail_DetectSettings_task, 10);
		
		final ProcessBuilder processBuilder= new ProcessBuilder(this.configModel.getExecCommand(Exec.TERM));
		processBuilder.command().add("--no-save"); //$NON-NLS-1$
		processBuilder.command().add("--slave"); //$NON-NLS-1$
		processBuilder.command().add("-e"); //$NON-NLS-1$
		processBuilder.command().add(DETECT_COMMAND);
		
		final Map<String, String> envp= processBuilder.environment();
		try {
			final DefaultLocalConfigurator setup= new DefaultLocalConfigurator(this.configModel);
			LaunchUtils.configureEnvironment(envp, null,
					setup.getEnvironmentsVariables(DefaultLocalConfigurator.MINIMAL_SETUP) );
		}
		catch (final StatusException e) {
			throw StatusUtils.convert(e);
		}
		
		monitor.worked(1);
		
		final ProcessOutputCollector reader= new ProcessOutputCollector(processBuilder, "'Detect R settings'", monitor); //$NON-NLS-1$
		final String output= reader.collect();
		final int start= output.indexOf(DETECT_START);
		if (start >= 0) {
			final String[] lines= DETECT_ITEM_PATTERN.split(output.substring(start));
			if (lines.length == DETECT_LENGTH) {
				updateLibraries(this.configModel.getRLibGroup(RLibGroup.R_DEFAULT),
						lines[DETECT_R_DEFAULT], lines[DETECT_R_HOME]);
				
				final RLibGroupWorkingCopy group= this.configModel.getRLibGroup(RLibGroup.R_SITE);
				updateLibraries(group, lines[DETECT_R_SITE], lines[DETECT_R_HOME]);
				if (group.getLibLocations().isEmpty()) {
					group.getLibLocations().add(group.newLibrary(BasicREnvConfiguration.DEFAULT_R_SITE_LOCATION_DIRECTORY));
				}
				updateLibraries(this.configModel.getRLibGroup(RLibGroup.R_OTHER),
						lines[DETECT_R_OTHER], lines[DETECT_R_HOME]);
				updateLibraries(this.configModel.getRLibGroup(RLibGroup.R_USER),
						lines[DETECT_R_USER], lines[DETECT_R_HOME]);
				
				this.configModel.setRDocDirectory(checkDir(lines[DETECT_R_DOC_DIR], lines[DETECT_R_HOME]));
				this.configModel.setRShareDirectory(checkDir(lines[DETECT_R_SHARE_DIR], lines[DETECT_R_HOME]));
				this.configModel.setRIncludeDirectory(checkDir(lines[DETECT_R_INCLUDE_DIR], lines[DETECT_R_HOME]));
				
				if (lines[DETECT_R_ARCHVAR].length() > 0) {
					this.configModel.setRArch(lines[DETECT_R_ARCHVAR]);
				}
				else if (lines[DETECT_R_ARCH].length() > 0 && this.configModel.getRArch() == null) {
					this.configModel.setRArch(lines[DETECT_R_ARCH]);
				}
				this.configModel.setROS(lines[DETECT_R_OS]);
				return;
			}
		}
		throw new CoreException(new Status(IStatus.ERROR, RUI.BUNDLE_ID, -1,
				"Unexpected output:\n" + output, null)); //$NON-NLS-1$
	}
	
	private void updateLibraries(final RLibGroupWorkingCopy group, final String var, final String rHome) {
		final List<RLibLocation> libraries= group.getLibLocations();
		libraries.clear();
		final String[] locations= DETECT_PATH_PATTERN.split(var);
		final IPath rHomePath= new Path(rHome);
		final IPath userHomePath= new Path(System.getProperty("user.home")); //$NON-NLS-1$
		for (final String location : locations) {
			if (location.isEmpty()) {
				continue;
			}
			String s;
			final IPath path;
			if (location.startsWith("~/")) { //$NON-NLS-1$
				path= userHomePath.append(location.substring(2));
			}
			else {
				path= new Path(location);
			}
			if (rHomePath.isPrefixOf(path)) {
				s= R_HOME_DIRECTORY_VAR_STRING + '/' + path.makeRelativeTo(rHomePath).toString();
			}
			else if (userHomePath.isPrefixOf(path)) {
				s= "${user_home}/" + path.makeRelativeTo(userHomePath).toString(); //$NON-NLS-1$
			}
			else {
				s= path.toString();
			}
			libraries.add(group.newLibrary(s));
		}
	}
	
	private String checkDir(String dir, final String rHome) {
		if (dir != null && dir.length() > 0) {
			final IPath rHomePath= new Path(rHome);
			final IPath path= new Path(dir);
			if (rHomePath.isPrefixOf(path)) {
				dir= R_HOME_DIRECTORY_VAR_STRING + '/' + path.makeRelativeTo(rHomePath).toString();
			}
			return dir;
		}
		return null;
	}
	
}
