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

import org.eclipse.core.databinding.Binding;
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.WritableValue;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;

import org.eclipse.statet.ecommons.databinding.core.validation.UpdateableErrorValidator;
import org.eclipse.statet.ecommons.debug.ui.config.LaunchConfigTabWithDbc;
import org.eclipse.statet.ecommons.io.FileValidator;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.MessageUtils;

import org.eclipse.statet.internal.r.debug.ui.RLaunchingMessages;
import org.eclipse.statet.internal.r.ui.REnvSelectionComposite;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.launching.core.RLaunching;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.REnvConfiguration;
import org.eclipse.statet.rj.renv.core.REnvUtils;


/**
 * Launch configuration tab allowing to configure the R environment
 */
public class REnvTab extends LaunchConfigTabWithDbc {
	
	
	public static String readWorkingDirectory(final ILaunchConfiguration configuration)
			throws CoreException {
		String wd= configuration.getAttribute(RLaunching.ATTR_WORKING_DIRECTORY, (String) null);
		if (wd == null) {
			wd= ""; //$NON-NLS-1$
		}
		return wd;
	}
	
	public static void setWorkingDirectory(final ILaunchConfigurationWorkingCopy configuration,
			final String wd) {
		if (wd != null && wd.length() > 0) {
			configuration.setAttribute(RLaunching.ATTR_WORKING_DIRECTORY, wd);
		}
		else {
			configuration.removeAttribute(RLaunching.ATTR_WORKING_DIRECTORY);
		}
	}
	
	/**
	 * Reads the setting from the configuration, resolves the path and validates the directory.
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	public static IFileStore getWorkingDirectory(final ILaunchConfiguration configuration) throws CoreException {
		return getWorkingDirectoryValidator(configuration, true).getFileStore();
	}
	
	public static FileValidator getWorkingDirectoryValidator(final ILaunchConfiguration configuration, final boolean validate) throws CoreException {
		String path= readWorkingDirectory(configuration);
		if (path == null || path.trim().isEmpty()) {
			path= System.getProperty("user.dir"); //$NON-NLS-1$
		}
		final FileValidator validator= new FileValidator(true);
		validator.setOnDirectory(IStatus.OK);
		validator.setOnFile(IStatus.ERROR);
		validator.setResourceLabel(MessageUtils.removeMnemonics(RLaunchingMessages.REnv_Tab_WorkingDir_label));
		validator.setExplicit(path);
		if (validate && validator.validate(null).getSeverity() == IStatus.ERROR) {
			throw new CoreException(validator.getStatus());
		}
		return validator;
	}
	
	
/*-- --*/
	
	
	private final boolean local;
	
	private final IObservableValue<String> rEnvSettingValue;
	private Binding rEnvBinding;
	
	private REnvSelectionComposite rEnvControl;
	
	
	public REnvTab(final boolean local) {
		super();
		
		this.local= local;
		
		final Realm realm= getRealm();
		this.rEnvSettingValue= new WritableValue<>(realm, null, String.class);
	}
	
	
	@Override
	public String getName() {
		return RLaunchingMessages.REnv_Tab_title;
	}
	
	@Override
	public Image getImage() {
		return RUI.getImage(RUI.IMG_OBJ_R_RUNTIME_ENV);
	}
	
	@Override
	public void createControl(final Composite parent) {
		final Composite mainComposite= new Composite(parent, SWT.NONE);
		setControl(mainComposite);
		mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		mainComposite.setLayout(GridLayoutFactory.swtDefaults().create());
		
		Group group;
		group= new Group(mainComposite, SWT.NONE);
		group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		group.setText(RLaunchingMessages.REnv_Tab_REnvConfig_label+':');
		group.setLayout(LayoutUtils.newGroupGrid(1));
		if (this.local) {
			this.rEnvControl= new REnvSelectionComposite(group) {
				@Override
				protected boolean isValid(final REnvConfiguration rEnvConfig) {
					return super.isValid(rEnvConfig) && rEnvConfig.isLocal();
				}
			};
		}
		else {
			this.rEnvControl= new REnvSelectionComposite(group, true);
		}
		this.rEnvControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		
		Dialog.applyDialogFont(parent);
		initBindings();
	}
	
	@Override
	protected void addBindings(final DataBindingContext dbc, final Realm realm) {
		this.rEnvBinding= dbc.bindValue(
				this.rEnvControl.createObservable(realm),
				this.rEnvSettingValue,
				new UpdateValueStrategy<String, String>()
						.setAfterGetValidator(new UpdateableErrorValidator<>(
								this.rEnvControl.createValidator(dbc) )),
				null );
	}
	
	@Override
	public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) {
		if (this.local) {
			configuration.setAttribute(RLaunching.ATTR_RENV_CODE, RCore.DEFAULT_WORKBENCH_ENV_ID);
		}
	}
	
	@Override
	protected void doInitialize(final ILaunchConfiguration configuration) {
		try {
			final String code= configuration.getAttribute(RLaunching.ATTR_RENV_CODE, (String)null);
			this.rEnvSettingValue.setValue(code);
		} catch (final CoreException e) {
			this.rEnvSettingValue.setValue(null);
			logReadingError(e);
		}
		
	}
	
	@Override
	protected void doSave(final ILaunchConfigurationWorkingCopy configuration) {
		final String code= this.rEnvSettingValue.getValue();
		configuration.setAttribute(RLaunching.ATTR_RENV_CODE, code);
	}
	
	
	public REnv getSelectedEnv() {
		if (this.rEnvBinding != null) {
			final IStatus validationStatus= this.rEnvBinding.getValidationStatus().getValue();
			if (validationStatus != null && validationStatus.getSeverity() < IStatus.WARNING) { // note: warning means error which can be saved
				return REnvUtils.decode(this.rEnvSettingValue.getValue(), RCore.getREnvManager());
			}
		}
		return null;
	}
	
}
