/*=============================================================================#
 # 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.console.ui.launching;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
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.ValueChangeEvent;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.LabelProvider;
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.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
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.ui.PlatformUI;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.ecommons.databinding.core.validation.UpdateableErrorValidator;
import org.eclipse.statet.ecommons.debug.core.util.LaunchUtils;
import org.eclipse.statet.ecommons.debug.ui.config.InputArgumentsComposite;
import org.eclipse.statet.ecommons.debug.ui.config.LaunchConfigTabWithDbc;
import org.eclipse.statet.ecommons.debug.ui.util.HelpRequestor;
import org.eclipse.statet.ecommons.ui.SharedMessages;
import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.VariableFilterUtils;
import org.eclipse.statet.ecommons.ui.workbench.ResourceInputComposite;

import org.eclipse.statet.internal.r.console.ui.Messages;
import org.eclipse.statet.internal.r.console.ui.RConsoleUIPlugin;
import org.eclipse.statet.r.console.ui.IRConsoleHelpContextIds;
import org.eclipse.statet.r.console.ui.launching.RConsoleLaunching;
import org.eclipse.statet.r.core.renv.IREnvConfiguration;
import org.eclipse.statet.r.core.renv.IREnvConfiguration.Exec;
import org.eclipse.statet.r.launching.core.RLaunching;
import org.eclipse.statet.r.launching.ui.REnvTab;


/**
 * Main tab for R Console launch config.
 */
public class RConsoleMainTab extends LaunchConfigTabWithDbc {
	
	
	private class RArgumentsComposite extends InputArgumentsComposite {
		
		public RArgumentsComposite(final Composite parent) {
			super(parent);
		}
		
		@Override
		protected void fillToolMenu(final Menu menu) {
			super.fillToolMenu(menu);
			
			if (RConsoleMainTab.this.withHelp) {
				RConsoleMainTab.this.helpItem= new MenuItem(menu, SWT.PUSH);
				RConsoleMainTab.this.helpItem.setText(Messages.RConsole_MainTab_RunHelp_label);
				RConsoleMainTab.this.helpItem.addSelectionListener(new SelectionAdapter() {
					@Override
					public void widgetSelected(final SelectionEvent e) {
						queryHelp();
						getTextControl().setFocus();
					}
				});
				checkHelp(RConsoleMainTab.this.configCache);
			}
		}
	}
	
	private final RConsoleType[] types;
	private final RConsoleType defaultType;
	
	private final IObservableValue<RConsoleType> typeValue;
	private final IObservableValue<String> workingDirectoryValue;
	protected final IObservableValue<String> argumentsValue;
	
	private ComboViewer typesCombo;
	
	private ResourceInputComposite workingDirectoryControl;
	private RArgumentsComposite argumentsControl;
	
	boolean withHelp= false;
	private MenuItem helpItem;
	private ILaunchConfigurationTab rEnvTab;
	private ILaunchConfiguration configCache;
	
	
	public RConsoleMainTab() {
		super();
		this.types= loadTypes();
		this.defaultType= this.types[0];
		
		final Realm realm= getRealm();
		this.typeValue= new WritableValue<>(realm, null, RConsoleType.class);
		this.workingDirectoryValue= new WritableValue<>(realm, null, String.class);
		this.argumentsValue= new WritableValue<>(realm, "", String.class); //$NON-NLS-1$
	}
	
	
	protected RConsoleType[] loadTypes() {
		final List<RConsoleType> types= new ArrayList<>();
		types.add(new RConsoleType("RJ (default)", RConsoleLaunching.LOCAL_RJS, true, true, true)); //$NON-NLS-1$
		types.add(new RConsoleType("Rterm", RConsoleLaunching.LOCAL_RTERM, false, false, false)); //$NON-NLS-1$
		return types.toArray(new RConsoleType[types.size()]);
	}
	
	RConsoleType getSelectedType() {
		if (this.typeValue != null) {
			return this.typeValue.getValue();
		}
		return null;
	}
	
	@Override
	public String getName() {
		return Messages.RConsole_MainTab_name;
	}
	
	@Override
	public Image getImage() {
		return SharedUIResources.getImages().get(SharedUIResources.OBJ_MAIN_TAB_ID);
	}
	
	@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(new GridLayout());
		
		{	// Type
			final Composite composite= new Composite(mainComposite, SWT.NONE);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			composite.setLayout(LayoutUtils.newCompositeGrid(2));
			
			final Label label= new Label(composite, SWT.LEFT);
			label.setText(Messages.RConsole_MainTab_LaunchType_label+':');
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final String[] names= new String[this.types.length];
			for (int i= 0; i < this.types.length; i++) {
				names[i]= this.types[i].getName();
			}
			this.typesCombo= new ComboViewer(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
			this.typesCombo.setContentProvider(new ArrayContentProvider());
			this.typesCombo.setLabelProvider(new LabelProvider() {
				@Override
				public String getText(final Object element) {
					final RConsoleType type= (RConsoleType) element;
					return type.getName();
				}
			});
			this.typesCombo.setInput(this.types);
			this.typesCombo.getCombo().setVisibleItemCount(names.length);
			this.typesCombo.getControl().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			this.typesCombo.getControl().setEnabled(this.types.length > 1);
		}
		
		final Composite detailGroup= createTypeDetailGroup(mainComposite);
		if (detailGroup != null) {
			detailGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		}
		
		final Composite commandGroup= createROptionsGroup(mainComposite);
		commandGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		
		
		LayoutUtils.addSmallFiller(mainComposite, true);
		createFooter(mainComposite);
		
		Dialog.applyDialogFont(parent);
		
		initBindings();
		
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
				IRConsoleHelpContextIds.R_CONSOLE_LAUNCH );
	}
	
	private Composite createROptionsGroup(final Composite parent) {
		for (final ILaunchConfigurationTab tab : getLaunchConfigurationDialog().getTabs()) {
			if (tab instanceof REnvTab) {
				this.rEnvTab= tab;
				break;
			}
		}
		this.withHelp= (this.rEnvTab != null) && (getLaunchConfigurationDialog() instanceof TrayDialog);
		
		final Group group= new Group(parent, SWT.NONE);
		group.setLayout(LayoutUtils.newGroupGrid(3));
		group.setText("R options:");
		
		this.workingDirectoryControl= new ResourceInputComposite(group,
				ResourceInputComposite.STYLE_LABEL | ResourceInputComposite.STYLE_TEXT,
				ResourceInputComposite.MODE_DIRECTORY | ResourceInputComposite.MODE_OPEN,
				Messages.RConsole_MainTab_WorkingDir_label );
		this.workingDirectoryControl.setShowInsertVariable(true,
				VariableFilterUtils.DEFAULT_INTERACTIVE_FILTERS, null);
		this.workingDirectoryControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
		
		this.argumentsControl= new RArgumentsComposite(group);
		this.argumentsControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
		
		return group;
	}
	
	protected Composite createTypeDetailGroup(final Composite parent) {
		return null;
	}
	
	protected Composite getArgumentComposite() {
		return this.argumentsControl;
	}
	
	protected void createFooter(final Composite composite) {
		final Label note= new Label(composite, SWT.WRAP);
		note.setText(SharedMessages.Note_label + ": " + this.argumentsControl.getNoteText()); //$NON-NLS-1$
		note.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));
	}
	
	
	@Override
	protected void addBindings(final DataBindingContext dbc, final Realm realm) {
		IValidator typeValidator= null;
		if (getLaunchConfigurationDialog().getMode().equals(ILaunchManager.DEBUG_MODE)) {
			typeValidator= new UpdateableErrorValidator((
					final Object value) -> {
						final RConsoleType type= (RConsoleType) value;
						if (!type.isDebugSupported()) {
							return ValidationStatus.error(NLS.bind(
									"R launch type ''{0}'' does not support debug mode.",
									type.getName() ));
						}
						return ValidationStatus.ok();
					} );
		}
		dbc.bindValue(
				ViewersObservables.observeSingleSelection(this.typesCombo),
				this.typeValue,
				(typeValidator != null) ? 
						new UpdateValueStrategy().setAfterGetValidator(typeValidator) :
						null,
				null );
		
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify).observe(this.argumentsControl.getTextControl()),
				this.argumentsValue );
		
		this.workingDirectoryControl.getValidator().setOnEmpty(IStatus.OK);
		dbc.bindValue(
				this.workingDirectoryControl.getObservable(),
				this.workingDirectoryValue,
				new UpdateValueStrategy().setAfterGetValidator(
						new UpdateableErrorValidator(this.workingDirectoryControl.getValidator()) ),
				null );
		
		this.typeValue.addValueChangeListener(
				(final ValueChangeEvent<? extends RConsoleType> event) -> {
					final Object newValue= event.diff.getNewValue();
					updateType((RConsoleType) newValue);
				} );
	}
	
	public RConsoleType getType() {
		return this.typeValue.getValue();
	}
	
	protected IObservableValue<RConsoleType> getTypeValue() {
		return this.typeValue;
	}
	
	/**
	 * @param typeId
	 */
	protected void updateType(final RConsoleType type) {
	}
	
	
	@Override
	public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) {
		configuration.setAttribute(RConsoleLaunching.ATTR_TYPE, this.defaultType.getId()); //s
		configuration.setAttribute(RConsoleLaunching.ATTR_OPTIONS, ""); //$NON-NLS-1$
		configuration.setAttribute(RConsoleLaunching.ATTR_PIN_CONSOLE, false); 
	}
	
	@Override
	protected void doInitialize(final ILaunchConfiguration configuration) {
		String type= null;
		try {
			type= configuration.getAttribute(RConsoleLaunching.ATTR_TYPE, ""); //$NON-NLS-1$
			// convert old rterm to new rj
			if (type.equals("rterm")) { //$NON-NLS-1$
				type= RConsoleLaunching.LOCAL_RTERM;
			}
		} catch (final CoreException e) {
			type= ""; //$NON-NLS-1$
			logReadingError(e);
		}
		int i= 0;
		for (; i < this.types.length; i++) {
			if (this.types[i].getId().equals(type)) {
				this.typeValue.setValue(this.types[i]);
				break;
			}
		}
		if (i >= this.types.length) {
			this.typeValue.setValue(this.defaultType);
		}
		
		String wd= null;
		try {
			wd= REnvTab.readWorkingDirectory(configuration);
		}
		catch (final CoreException e) {
			wd= ""; //$NON-NLS-1$
			logReadingError(e);
		}
		this.workingDirectoryValue.setValue(wd);
		
		String options= null;
		try {
			options= configuration.getAttribute(RConsoleLaunching.ATTR_OPTIONS, ""); //$NON-NLS-1$
		} catch (final CoreException e) {
			options= ""; //$NON-NLS-1$
			logReadingError(e);
		}
		this.argumentsValue.setValue(options);
		
		checkHelp(configuration);
	}
	
	@Override
	public void activated(final ILaunchConfigurationWorkingCopy workingCopy) {
		checkHelp(workingCopy);
		super.activated(workingCopy);
	}
	
	@Override
	protected void doSave(final ILaunchConfigurationWorkingCopy configuration) {
		configuration.setAttribute(RConsoleLaunching.ATTR_TYPE, this.typeValue.getValue().getId());
		if (this.argumentsControl.isEnabled()) {
			configuration.setAttribute(RConsoleLaunching.ATTR_OPTIONS, this.argumentsValue.getValue());
		}
		else {
			configuration.removeAttribute(RConsoleLaunching.ATTR_OPTIONS);
		}
		
		REnvTab.setWorkingDirectory(configuration, this.workingDirectoryValue.getValue());
	}
	
	private void checkHelp(final ILaunchConfiguration configuration) {
		this.configCache= configuration;
		if (this.withHelp && this.helpItem != null) {
			this.helpItem.setEnabled(this.rEnvTab.isValid(this.configCache));
		}
	}
	
	private void queryHelp() {
		if (!this.withHelp) {
			return;
		}
		try {
			final List<String> cmdLine= new ArrayList<>();
			final ILaunchConfigurationDialog dialog= getLaunchConfigurationDialog();
			
			// r env
			final IREnvConfiguration renv= RLaunching.getREnvConfig(this.configCache, true);
			
			cmdLine.addAll(0, renv.getExecCommand(Exec.TERM));
			
			cmdLine.add("--help"); //$NON-NLS-1$
			final ProcessBuilder processBuilder= new ProcessBuilder(cmdLine);
			final HelpRequestor helper= new HelpRequestor(processBuilder, (TrayDialog) dialog);
			
			final Map<String, String> envp= processBuilder.environment();
			LaunchUtils.configureEnvironment(envp, this.configCache, renv.getEnvironmentsVariables());
			
			dialog.run(true, true, helper);
			updateLaunchConfigurationDialog();
		}
		catch (final CoreException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, RConsoleUIPlugin.BUNDLE_ID, -1,
					Messages.RConsole_MainTab_error_CannotRunHelp_message, e ),
					StatusManager.LOG | StatusManager.SHOW);
		}
		catch (final InvocationTargetException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, RConsoleUIPlugin.BUNDLE_ID, -1,
					Messages.RConsole_MainTab_error_WhileRunningHelp_message, e.getTargetException() ),
					StatusManager.LOG | StatusManager.SHOW);
		}
		catch (final InterruptedException e) {
			// canceled
		}
	}
	
	@Override
	public void dispose() {
		if (this.withHelp) {
			HelpRequestor.closeHelpTray((TrayDialog) getLaunchConfigurationDialog());
		}
		super.dispose();
	}
	
}
