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

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.typed.BeanProperties;
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.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.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
import org.eclipse.jface.databinding.viewers.typed.ViewerProperties;
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.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.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.Nullable;

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.models.AbstractSettingsModelObject;
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.RConsoleUIPlugin;
import org.eclipse.statet.r.cmd.ui.launching.RCmdLaunching;
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 to configure R CMD tool launch configs.
 */
public class RCmdMainTab extends LaunchConfigTabWithDbc {
	
	public static final String NS= "org.eclipse.statet.r.debug/RCmd/"; //$NON-NLS-1$
	
	private static class Cmd extends AbstractSettingsModelObject {
		
		public final static int PACKAGE_DIR= 1;
		public final static int PACKAGE_DIR_OR_ARCHIVE= 2;
		public final static int DOC= 3;
		public final static int DOC_OR_DIR= 4;
		public final static int CUSTOM= 5;
		
		private final String name;
		private String command;
		private final int type;
		
		public Cmd(final String name, final String command, final int type) {
			this.name= name;
			this.command= command;
			this.type= type;
		}
		
		public String getName() {
			return this.name;
		}
		
		public int getType() {
			return this.type;
		}
		
		public void setCommand(final String command) {
			this.command= command.trim();
		}
		
		public String getCommand() {
			return this.command;
		}
		
	}
	
	
	private Cmd[] commands;
	private Cmd customCommand;
	
	private final IObservableValue<Cmd> cmdValue;
	private final IObservableValue<String> argumentsValue;
	private final IObservableValue<String> resourceValue;
	
	private final IObservableValue<String> workingDirectoryValue;
	
	private ComboViewer cmdCombo;
	private Text cmdText;
	private Button helpButton;
	private InputArgumentsComposite argumentsControl;
	private ResourceInputComposite resourceControl;
	
	private ResourceInputComposite workingDirectoryControl;
	
	boolean withHelp= false;
	private ILaunchConfigurationTab rEnvTab;
	private ILaunchConfiguration configCache;
	
	
	public RCmdMainTab() {
		super();
		createCommands();
		
		final Realm realm= getRealm();
		this.cmdValue= new WritableValue<>(realm, null, Cmd.class);
		this.argumentsValue= new WritableValue<>(realm, null, String.class);
		this.resourceValue= new WritableValue<>(realm, null, String.class);
		this.workingDirectoryValue= new WritableValue<>(realm, null, String.class);
	}
	
	private void createCommands() {
		final List<Cmd> commands= new ArrayList<>();
		commands.add(new Cmd(Messages.RCmd_CmdCheck_name, "CMD check", Cmd.PACKAGE_DIR_OR_ARCHIVE)); //$NON-NLS-1$
		commands.add(new Cmd(Messages.RCmd_CmdBuild_name, "CMD build", Cmd.PACKAGE_DIR)); //$NON-NLS-1$
		commands.add(new Cmd(Messages.RCmd_CmdInstall_name, "CMD INSTALL", Cmd.PACKAGE_DIR_OR_ARCHIVE)); //$NON-NLS-1$
		commands.add(new Cmd(Messages.RCmd_CmdRemove_name, "CMD REMOVE", Cmd.PACKAGE_DIR)); //$NON-NLS-1$
		commands.add(new Cmd(Messages.RCmd_CmdRdconv_name, "CMD Rdconv", Cmd.DOC)); //$NON-NLS-1$
		commands.add(new Cmd(Messages.RCmd_CmdRd2dvi_name, "CMD Rd2dvi", Cmd.DOC_OR_DIR)); //$NON-NLS-1$
		commands.add(new Cmd(Messages.RCmd_CmdRd2txt_name, "CMD Rd2txt", Cmd.DOC)); //$NON-NLS-1$
		commands.add(new Cmd(Messages.RCmd_CmdSd2Rd_name, "CMD Sd2Rd", Cmd.DOC)); //$NON-NLS-1$
		commands.add(new Cmd(Messages.RCmd_CmdRoxygen_name, "CMD roxygen", Cmd.PACKAGE_DIR)); //$NON-NLS-1$
		commands.add(new Cmd(Messages.RCmd_CmdSweave_name, "CMD Sweave", Cmd.DOC)); //$NON-NLS-1$
		this.customCommand= new Cmd(Messages.RCmd_CmdOther_name, "", Cmd.CUSTOM); //$NON-NLS-1$
		commands.add(this.customCommand);
		
		this.commands= commands.toArray(new Cmd[commands.size()]);
		resetCommands();
	}
	
	private void resetCommands() {
		this.customCommand.command= "CMD "; //$NON-NLS-1$
	}
	
	@Override
	public String getName() {
		return Messages.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.setLayout(LayoutUtils.newTabGrid(1));
		
		Group group;
		group= new Group(mainComposite, SWT.NONE);
		group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		group.setText(Messages.MainTab_Cmd_label);
		createCommandControls(group);
		
		{	final Composite composite= createWorkingDirectoryGroup(mainComposite);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		}
		
		{	final Label note= new Label(mainComposite, SWT.WRAP);
			note.setText(SharedMessages.Note_label + ": " + this.argumentsControl.getNoteText()); //$NON-NLS-1$
			note.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, true));
		}
		
		Dialog.applyDialogFont(parent);
		
		initBindings();
	}
	
	private Composite createWorkingDirectoryGroup(final Composite parent) {
		final ResourceInputComposite control= new ResourceInputComposite(parent,
				ResourceInputComposite.STYLE_GROUP | ResourceInputComposite.STYLE_TEXT,
				ResourceInputComposite.MODE_DIRECTORY | ResourceInputComposite.MODE_OPEN,
				Messages.MainTab_WorkingDir_label);
		control.setShowInsertVariable(true, 
				VariableFilterUtils.DEFAULT_INTERACTIVE_FILTERS, null );
		this.workingDirectoryControl= control;
		
		return control;
	}
	
	private void createCommandControls(final Composite container) {
		for (final ILaunchConfigurationTab tab : getLaunchConfigurationDialog().getTabs()) {
			if (tab instanceof REnvTab) {
				this.rEnvTab= tab;
				break;
			}
		}
		this.withHelp= (this.rEnvTab != null) && (getLaunchConfigurationDialog() instanceof TrayDialog);
		
		container.setLayout(LayoutUtils.newGroupGrid(3));
		
		final String[] names= new String[this.commands.length];
		for (int i= 0; i < this.commands.length; i++) {
			names[i]= this.commands[i].getName();
		}
		this.cmdCombo= new ComboViewer(container, SWT.DROP_DOWN | SWT.READ_ONLY);
		this.cmdCombo.setContentProvider(new ArrayContentProvider());
		this.cmdCombo.setLabelProvider(new LabelProvider() {
			@Override
			public String getText(final Object element) {
				final Cmd cmd= (Cmd) element;
				return cmd.getName();
			}
		});
		this.cmdCombo.setInput(this.commands);
		this.cmdCombo.getCombo().setVisibleItemCount(names.length);
		this.cmdCombo.getControl().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		
		this.cmdText= new Text(container, SWT.BORDER | SWT.SINGLE);
		this.cmdText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, this.withHelp ? 1 : 2, 1));
		
		if (this.withHelp) {
			this.helpButton= new Button(container, SWT.PUSH);
			this.helpButton.setText(Messages.MainTab_RunHelp_label);
			this.helpButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(final SelectionEvent e) {
					queryHelp();
				}
			});
			final GridData gd= new GridData(SWT.FILL, SWT.CENTER, false, false);
			gd.widthHint= LayoutUtils.hintWidth(this.helpButton);
			this.helpButton.setLayoutData(gd);
		}
		
		LayoutUtils.addSmallFiller(container, false);
		this.argumentsControl= new InputArgumentsComposite(container);
		this.argumentsControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
		
		this.resourceControl= new ResourceInputComposite(container,
				ResourceInputComposite.STYLE_LABEL | ResourceInputComposite.STYLE_TEXT,
				ResourceInputComposite.MODE_FILE | ResourceInputComposite.MODE_OPEN,
				"" ); //$NON-NLS-1$
		this.resourceControl.setShowInsertVariable(true,
				ImCollections.newList(VariableFilterUtils.EXCLUDE_JAVA_FILTER),
				null );
		this.resourceControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
	}
	
	@Override
	protected void addBindings(final DataBindingContext dbc) {
		final IObservableValue<Cmd> cmdSelection= ViewerProperties.singleSelection(Cmd.class)
				.observe(this.cmdCombo);
		dbc.bindValue(
				cmdSelection,
				this.cmdValue );
		final IValidator<@Nullable String> cmdValidator= (final @Nullable String value) -> {
					if (value == null || value.trim().isEmpty()) {
						return ValidationStatus.warning(Messages.MainTab_error_MissingCMD_message);
					}
					return ValidationStatus.ok();
				};
		
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify)
						.observe(this.cmdText),
				BeanProperties.value(Cmd.class, "command", String.class) //$NON-NLS-1$
						.observeDetail(cmdSelection),
				new UpdateValueStrategy<String, String>()
						.setAfterGetValidator(cmdValidator),
				new UpdateValueStrategy<String, String>()
						.setBeforeSetValidator(cmdValidator) );
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify)
						.observe(this.argumentsControl.getTextControl()),
				this.argumentsValue );
		
		this.resourceControl.getValidator().setOnLateResolve(IStatus.WARNING);
		this.resourceControl.getValidator().setOnEmpty(IStatus.OK);
		this.resourceControl.getValidator().setIgnoreRelative(true);
		final Binding resourceBinding= dbc.bindValue(
				this.resourceControl.getObservable(),
				this.resourceValue,
				new UpdateValueStrategy<String, String>()
						.setAfterGetValidator(new UpdateableErrorValidator<>(
								this.resourceControl.getValidator() )),
				null );
		cmdSelection.addValueChangeListener(new IValueChangeListener<Cmd>() {
			@Override
			public void handleValueChange(final ValueChangeEvent<? extends Cmd> event) {
				final Cmd cmd= event.diff.getNewValue();
				if (cmd != null) {
					RCmdMainTab.this.cmdText.setEditable(cmd.getType() == Cmd.CUSTOM);
					String label;
					int mode= 0;
					switch (cmd.getType()) {
					case Cmd.PACKAGE_DIR:
						label= Messages.MainTab_Resource_PackageDir_label;
						mode= ResourceInputComposite.MODE_DIRECTORY;
						break;
					case Cmd.PACKAGE_DIR_OR_ARCHIVE:
						label= Messages.MainTab_Resource_PackageDirOrArchive_label;
						mode= ResourceInputComposite.MODE_FILE | ResourceInputComposite.MODE_DIRECTORY;
						break;
					case Cmd.DOC:
						label= Messages.MainTab_Resource_Doc_label;
						mode= ResourceInputComposite.MODE_FILE;
						break;
					case Cmd.DOC_OR_DIR:
						label= Messages.MainTab_Resource_DocOrDir_label;
						mode= ResourceInputComposite.MODE_FILE | ResourceInputComposite.MODE_DIRECTORY;
						break;
					default: // Cmd.CUSTOM:
						label= Messages.MainTab_Resource_Other_label;
						mode= ResourceInputComposite.MODE_FILE | ResourceInputComposite.MODE_DIRECTORY;
						break;
					}
					RCmdMainTab.this.resourceControl.setResourceLabel(label);
					RCmdMainTab.this.resourceControl.setMode(mode | ResourceInputComposite.MODE_OPEN);
					resourceBinding.validateTargetToModel();
				}
			}
		});
		
		this.workingDirectoryControl.getValidator().setOnEmpty(IStatus.OK);
		dbc.bindValue(
				this.workingDirectoryControl.getObservable(),
				this.workingDirectoryValue,
				new UpdateValueStrategy<String, String>()
						.setAfterGetValidator(new UpdateableErrorValidator<>(
								this.workingDirectoryControl.getValidator() )),
				null );
	}
	
	
	@Override
	public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) {
		configuration.setAttribute(RCmdLaunching.R_CMD_COMMAND_ATTR_NAME, this.commands[0].getCommand());
		configuration.setAttribute(RCmdLaunching.R_CMD_OPTIONS_ATTR_NAME, ""); //$NON-NLS-1$
		configuration.setAttribute(RCmdLaunching.R_CMD_RESOURCE_ATTR_NAME, "${resource_loc}"); //$NON-NLS-1$
		REnvTab.setWorkingDirectory(configuration, ""); //$NON-NLS-1$
	}
	
	@Override
	protected void doInitialize(final ILaunchConfiguration configuration) {
		resetCommands();
		
		{	final String command= readAttribute(configuration,
					RCmdLaunching.R_CMD_COMMAND_ATTR_NAME,
					"" ); //$NON-NLS-1$
			Cmd cmd= null;
			for (final Cmd candidate : this.commands) {
				if (candidate.getCommand().equals(command)) {
					cmd= candidate;
					break;
				}
			}
			if (cmd == null) {
				this.customCommand.setCommand(command);
				cmd= this.customCommand;
			}
			this.cmdValue.setValue(cmd);
		}
		this.argumentsValue.setValue(readAttribute(configuration,
				RCmdLaunching.R_CMD_OPTIONS_ATTR_NAME,
				"" )); //$NON-NLS-1$
		this.resourceValue.setValue(readAttribute(configuration,
				RCmdLaunching.R_CMD_RESOURCE_ATTR_NAME,
				"" )); //$NON-NLS-1$
		
		{	String value;
			try {
				value= REnvTab.readWorkingDirectory(configuration);
			}
			catch (final CoreException e) {
				value= ""; //$NON-NLS-1$
				logReadingError(e);
			}
			this.workingDirectoryValue.setValue(value);
		}
		
		checkHelp(configuration);
	}
	
	@Override
	public void activated(final ILaunchConfigurationWorkingCopy workingCopy) {
		checkHelp(workingCopy);
		super.activated(workingCopy);
	}
	
	private void checkHelp(final ILaunchConfiguration configuration) {
		this.configCache= configuration;
		if (this.withHelp) {
			this.helpButton.setEnabled(this.rEnvTab.isValid(this.configCache));
		}
	}
	
	@Override
	protected void doSave(final ILaunchConfigurationWorkingCopy configuration) {
		configuration.setAttribute(RCmdLaunching.R_CMD_COMMAND_ATTR_NAME, this.cmdValue.getValue().getCommand());
		configuration.setAttribute(RCmdLaunching.R_CMD_OPTIONS_ATTR_NAME, this.argumentsValue.getValue());
		configuration.setAttribute(RCmdLaunching.R_CMD_RESOURCE_ATTR_NAME, this.resourceValue.getValue());
		REnvTab.setWorkingDirectory(configuration, this.workingDirectoryValue.getValue());
	}
	
	
	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);
			
			final String cmd= this.cmdValue.getValue().getCommand().trim();
			if (cmd.length() != 0) {
				cmdLine.addAll(Arrays.asList(cmd.split(" "))); //$NON-NLS-1$
			}
			String arg1= null;
			if (cmdLine.size() > 0) {
				arg1= cmdLine.remove(0);
			}
			cmdLine.addAll(0, renv.getExecCommand(arg1, EnumSet.of(Exec.CMD)));
			
			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.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.MainTab_error_WhileRunningHelp_message, e.getTargetException()),
					StatusManager.LOG | StatusManager.SHOW);
		}
		catch (final InterruptedException e) {
		}
	}
	
	@Override
	public void dispose() {
		if (this.withHelp) {
			HelpRequestor.closeHelpTray((TrayDialog) getLaunchConfigurationDialog());
		}
		super.dispose();
	}
	
}
