/*=============================================================================#
 # Copyright (c) 2017, 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.apps.ui.variables;

import static org.eclipse.ui.IWorkbenchCommandConstants.NAVIGATE_COLLAPSE_ALL;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.commands.IElementUpdater;
import org.eclipse.ui.handlers.CollapseAllHandler;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.menus.UIElement;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.services.IServiceLocator;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.ts.core.ActiveToolListener;
import org.eclipse.statet.jcommons.ts.core.ActiveToolListener.ActiveToolEvent;
import org.eclipse.statet.jcommons.ts.core.Tool;
import org.eclipse.statet.jcommons.ts.core.ToolProvider;

import org.eclipse.statet.ecommons.ts.ui.workbench.WorkbenchToolRegistry;
import org.eclipse.statet.ecommons.ts.ui.workbench.WorkbenchToolRegistryListener;
import org.eclipse.statet.ecommons.ts.ui.workbench.WorkbenchToolSessionData;
import org.eclipse.statet.ecommons.ui.actions.HandlerCollection;
import org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem;
import org.eclipse.statet.ecommons.ui.actions.UIActions;
import org.eclipse.statet.ecommons.ui.components.StatusInfo;
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.ecommons.ui.util.ViewActionUtil;
import org.eclipse.statet.ecommons.ui.workbench.ContextHandlers;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;

import org.eclipse.statet.base.ui.StatetImages;
import org.eclipse.statet.internal.r.apps.ui.RAppUIPlugin;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorCommandIds;
import org.eclipse.statet.ltk.ui.util.ViewerDragSupport;
import org.eclipse.statet.nico.ui.NicoUI;
import org.eclipse.statet.nico.ui.actions.AbstractToolHandler;
import org.eclipse.statet.r.apps.ui.AppRegistry;
import org.eclipse.statet.r.apps.ui.AppRegistry.AppStateEvent;
import org.eclipse.statet.r.apps.ui.RApp;
import org.eclipse.statet.r.apps.ui.VariablesData;
import org.eclipse.statet.r.console.core.RConsoleTool;
import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.r.console.core.RProcessREnvironment;
import org.eclipse.statet.r.ui.rtool.CopyRElementHandler;
import org.eclipse.statet.r.ui.rtool.PrintRElementHandler;
import org.eclipse.statet.r.ui.rtool.RElementViewerDragSourceListener;
import org.eclipse.statet.r.ui.util.CopyRElementNameHandler;
import org.eclipse.statet.r.ui.util.RElementInputContentProvider;
import org.eclipse.statet.r.ui.util.RElementInputLabelProvider;
import org.eclipse.statet.r.ui.util.RElementInputUtils;
import org.eclipse.statet.rj.data.RReference;


@NonNullByDefault
public class AppVarView extends ViewPart implements ToolProvider {
	
	
	public static final String VIEW_ID= "org.eclipse.statet.r.apps.views.VariableViewer"; //$NON-NLS-1$
	
	
	private static final String REFRESH_COMMAND_ID= IWorkbenchCommandConstants.FILE_REFRESH;
	
	private static final String FILTER_INCLUDE_INTERNAL_COMMAND_ID= "Filter.IncludeInternal"; //$NON-NLS-1$
	
	private static final String PRINT_COMMAND_ID= "org.eclipse.statet.r.commands.RunPrintInR"; //$NON-NLS-1$
	
	
	private static final String FILTER_INCLUDE_INTERNAL_SETTINGS_KEY= "Filter.IncludeInternal.enabled"; //$NON-NLS-1$
	
	
	private class RefreshHandler extends AbstractToolHandler<RProcess> {
		
		public RefreshHandler() {
			super(RConsoleTool.TYPE, null, AppVarView.this, getSite());
			init();
		}
		
		
		@Override
		protected boolean evaluateIsEnabled(final RProcess tool, final @Nullable Object evaluationContext) {
			return (super.evaluateIsEnabled(tool, evaluationContext)
					&& getApp() != null );
		}
		
		protected void refreshElements() {
			WorkbenchUIUtils.refreshCommandElements(REFRESH_COMMAND_ID, this, null);
		}
		
		@Override
		protected @Nullable Object execute(final RProcess tool, final ExecutionEvent event) {
			final RApp app= getApp();
			if (app != null) {
				app.refreshVariables();
			}
			return null;
		}
		
	}
	
	private class FilterInternalHandler extends AbstractHandler implements IElementUpdater {
		
		@Override
		public @Nullable Object execute(final ExecutionEvent event) throws ExecutionException {
			AppVarView.this.filterIncludeInternal= !AppVarView.this.filterIncludeInternal;
			AppVarView.this.settings.put(FILTER_INCLUDE_INTERNAL_SETTINGS_KEY, AppVarView.this.filterIncludeInternal);
			updateFilter();
			return null;
		}
		
		@Override
		public void updateElement(final UIElement element, final Map parameters) {
			WorkbenchUIUtils.aboutToUpdateCommandsElements(this, element);
			try {
				element.setChecked(AppVarView.this.filterIncludeInternal);
			}
			finally {
				WorkbenchUIUtils.finalizeUpdateCommandsElements(this);
			}
		}
		
	}
	
	
	private IDialogSettings settings;
	
	final Object sourceLock= new Object();
	private WorkbenchToolRegistryListener toolRegistryListener;
	private @Nullable RProcess process;
	private final CopyOnWriteIdentityListSet<ActiveToolListener> toolListeners= new CopyOnWriteIdentityListSet<>();
	
	private AppRegistry.Listener appRegistryListener;
	private @Nullable RApp app;
	
	
	private TreeViewer treeViewer;
	
	private final ContentJob inputUpdater= new ContentJob(this);
	private boolean isUpdating;
	
	private boolean filterIncludeInternal;
	private String filterText;
	
	private RElementInputContentProvider<AppVarInput> inputContentProvider;
	
	
	private ViewActionUtil actionUtil;
	private ContextHandlers handlers;
	
	private @Nullable Object currentInfoObject;
	
	
	private @Nullable RApp shownByLauncher;
	
	
	@SuppressWarnings("null")
	public AppVarView() {
	}
	
	@Override
	public void dispose() {
		if (this.appRegistryListener != null) {
			AppRegistry.getInstance().removeListener(this.appRegistryListener);
			this.appRegistryListener= null;
		}
		if (this.toolRegistryListener != null) {
			NicoUI.getToolRegistry().removeListener(this.toolRegistryListener);
			this.toolRegistryListener= null;
		}
		setTool(null, false);
		
		if (this.handlers != null) {
			this.handlers.dispose();
			this.handlers= null;
		}
		
		super.dispose();
	}
	
	
	@Override
	public void init(final IViewSite site, final @Nullable IMemento memento) throws PartInitException {
		super.init(site, memento);
		
		this.settings= DialogUtils.getDialogSettings(RAppUIPlugin.getInstance(), "AppVarBrowser");
		
		this.filterIncludeInternal= this.settings.getBoolean(FILTER_INCLUDE_INTERNAL_SETTINGS_KEY);
	}
	
	@Override
	public void createPartControl(final Composite parent) {
		parent.setLayout(LayoutUtils.newSashGrid());
		
		this.treeViewer= createTreeViewer(parent);
		this.treeViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		
		final IPostSelectionProvider treeSelectionProvider= this.treeViewer;
		treeSelectionProvider.addPostSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(final SelectionChangedEvent event) {
				updateSelectionInfo((ITreeSelection) event.getSelection());
			}
		});
		
		final IViewSite site= getViewSite();
		site.setSelectionProvider(treeSelectionProvider);
		this.actionUtil= new ViewActionUtil(this);
		this.handlers= new ContextHandlers(site.getService(IHandlerService.class));
		initActions(site, this.handlers);
		contributeToActionBars(site, site.getActionBars(), this.handlers);
		hookContextMenu();
		
		// listen on console changes
		final WorkbenchToolRegistry toolRegistry= NicoUI.getToolRegistry();
		this.toolRegistryListener= new WorkbenchToolRegistryListener() {
			@Override
			public void toolSessionActivated(final WorkbenchToolSessionData sessionData) {
				final Tool tool= sessionData.getTool();
				UIAccess.getDisplay().syncExec(new Runnable() {
					@Override
					public void run() {
						setTool(tool, true);
					}
				});
			}
			@Override
			public void toolTerminated(final WorkbenchToolSessionData sessionData) {
				final Tool tool= sessionData.getTool();
				UIAccess.getDisplay().syncExec(new Runnable() {
					@Override
					public void run() {
						if (tool == getTool()) {
							setTool(null, true);
						}
					}
				});
			}
		};
		toolRegistry.addListener(this.toolRegistryListener, getViewSite().getPage());
		
		this.appRegistryListener= new AppRegistry.Listener() {
			@Override
			public void onAppStateChanged(final AppStateEvent event) {
				UIAccess.getDisplay(getSite().getShell()).asyncExec(() -> {
					switch (event.getType()) {
					case AppRegistry.APP_STARTED:
						if (event.getApp().getTool() == getTool()) {
							setApp(event.getApp(), true);
						}
						break;
					case AppRegistry.APP_STOPPED:
						if (event.getApp() == getApp()) {
							setApp(null, true);
						}
						break;
					default:
						break;
					}
				});
			}
		};
		AppRegistry.getInstance().addListener(this.appRegistryListener);
		
		setTool(toolRegistry.getActiveToolSession(getViewSite().getPage()).getTool(), true);
	}
	
	private TreeViewer createTreeViewer(final Composite parent) {
		final TreeViewer viewer= new TreeViewer(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI);
		
		viewer.setLabelProvider(new RElementInputLabelProvider());
		
		viewer.setUseHashlookup(true);
		this.inputContentProvider= new RElementInputContentProvider();
		viewer.setContentProvider(this.inputContentProvider);
		viewer.setInput(this);
		
		return viewer;
	}
	
	protected void initActions(final IServiceLocator serviceLocator, final ContextHandlers handlers) {
		handlers.addActivate(REFRESH_COMMAND_ID, new RefreshHandler());
		
		final CopyRElementHandler copyHandler= new CopyRElementHandler(this.actionUtil,
				(ILabelProvider) this.treeViewer.getLabelProvider() );
		handlers.addActivate(IWorkbenchCommandConstants.EDIT_COPY, copyHandler);
		handlers.addActivate(ISourceEditorCommandIds.COPY_ELEMENT_NAME,
				new CopyRElementNameHandler(this.actionUtil) );
		
		final ViewerDragSupport dragSupport= new ViewerDragSupport(this.treeViewer);
		dragSupport.addDragSourceListener(new RElementViewerDragSourceListener(
				copyHandler, this.treeViewer ));
		dragSupport.init();
		
		handlers.addActivate(PRINT_COMMAND_ID,
				new PrintRElementHandler(this.actionUtil) );
		
		handlers.add(FILTER_INCLUDE_INTERNAL_COMMAND_ID,
				new FilterInternalHandler() );
		
		handlers.addActivate(NAVIGATE_COLLAPSE_ALL,
				new CollapseAllHandler(this.treeViewer) );
		RElementInputUtils.addDoubleClickExpansion(this.treeViewer);
	}
	
	protected void contributeToActionBars(final IServiceLocator serviceLocator,
			final IActionBars actionBars, final HandlerCollection handlers) {
		final IMenuManager menuManager= actionBars.getMenuManager();
		final IToolBarManager toolbarManager= actionBars.getToolBarManager();
		
		menuManager.add(new HandlerContributionItem(
				new CommandContributionItemParameter(serviceLocator,
						null, HandlerContributionItem.NO_COMMAND_ID, null,
						null, null, null,
						"Show &Internal Variables ('.*')", null, null,
						HandlerContributionItem.STYLE_CHECK, null, false ),
				nonNullAssert(handlers.get(FILTER_INCLUDE_INTERNAL_COMMAND_ID)) ));
		
		menuManager.add(new Separator());
		menuManager.add(new HandlerContributionItem(
				new CommandContributionItemParameter(serviceLocator,
						"Refresh", REFRESH_COMMAND_ID, null, //$NON-NLS-1$
						StatetImages.getDescriptor(StatetImages.TOOL_REFRESH), StatetImages.getDescriptor(StatetImages.TOOLD_REFRESH), null,
						"&Refresh", null, null,
						HandlerContributionItem.STYLE_PUSH, null, false ),
				handlers ));
		
		toolbarManager.add(new HandlerContributionItem(
				new CommandContributionItemParameter(serviceLocator,
						null, CollapseAllHandler.COMMAND_ID, null,
						null, null, null,
						null, null, null,
						HandlerContributionItem.STYLE_PUSH, null, false ),
				nonNullAssert(handlers.get(NAVIGATE_COLLAPSE_ALL)) ));
	}
	
	private void hookContextMenu() {
		final MenuManager menuManager= new MenuManager("ContextMenu", //$NON-NLS-1$
				"org.eclipse.statet.r.apps.menus.VariablesViewContextMenu" ); //$NON-NLS-1$
		menuManager.setRemoveAllWhenShown(true);
		menuManager.addMenuListener(this::fillContextMenu);
		final Menu contextMenu= menuManager.createContextMenu(this.treeViewer.getTree());
		this.treeViewer.getTree().setMenu(contextMenu);
		getSite().registerContextMenu(menuManager, this.treeViewer);
	}
	
	private void fillContextMenu(final IMenuManager m) {
		final IServiceLocator serviceLocator= getSite();
		final ContextHandlers handlers= this.handlers;
		
		m.add(new Separator(UIActions.EDIT_GROUP_ID));
		m.add(new HandlerContributionItem(
				new CommandContributionItemParameter(serviceLocator,
						"Copy", IWorkbenchCommandConstants.EDIT_COPY, null, //$NON-NLS-1$
						null, null, null,
						null, null, null,
						HandlerContributionItem.STYLE_PUSH, null, false ),
				handlers ));
		m.add(new HandlerContributionItem(
				new CommandContributionItemParameter(serviceLocator,
						"Copy.ElementName", ISourceEditorCommandIds.COPY_ELEMENT_NAME, null, //$NON-NLS-1$
						null, null, null,
						null, null, null,
						HandlerContributionItem.STYLE_PUSH, null, false ),
				handlers ));
		m.add(new Separator());
		m.add(new HandlerContributionItem(
				new CommandContributionItemParameter(serviceLocator,
						null, PRINT_COMMAND_ID, null,
						null, null, null,
						null, null, null,
						HandlerContributionItem.STYLE_PUSH, null, false ),
				handlers ));
		
		m.add(new Separator(UIActions.ADDITIONS_GROUP_ID));
	}
	
	@Override
	public void setFocus() {
		this.treeViewer.getControl().setFocus();
	}
	
	
	/** UI thread only (called by update job) */
	void updateView(final @Nullable AppVarInput input,
			final @Nullable List<RProcessREnvironment> updateEnvirs) {
		if (!UIAccess.isOkToUse(this.treeViewer)) {
			return;
		}
		this.isUpdating= true;
		
//		this.hoveringController.stop();
		
		this.inputContentProvider.setInput(input);
		
		final Set<RReference> previousReferences= this.inputContentProvider.resetUsedReferences();
		if (input != null && updateEnvirs != null) {
			for (final RProcessREnvironment entry : updateEnvirs) {
				this.treeViewer.refresh(entry, true);
			}
			if (!previousReferences.isEmpty()) {
				final Set<RReference> usedReferences= this.inputContentProvider.getUsedReferences();
				ITER_REFS: for (final RReference reference : previousReferences) {
					if (!usedReferences.contains(reference)) {
						// Update the envir copy in the viewer, if it refers to an updated envir
						for (final RProcessREnvironment entry : updateEnvirs) {
							if (entry.getHandle() == reference.getHandle()) {
								this.treeViewer.refresh(reference, true);
								// reference is readded automatically to new set, if necessary
								continue ITER_REFS;
							}
						}
						// Keep/readd the reference, if it refers to an envir in the search path
//						for (final ICombinedREnvironment entry : input.searchEnvirs) {
//							if (entry.getHandle() == reference.getHandle()) {
//								usedReferences.add(reference);
//								continue ITER_REFS;
//							}
//						}
					}
				}
			}
		}
		else {
			this.treeViewer.refresh(true);
		}
		
		updateSelectionInfo((ITreeSelection) this.actionUtil.getSelectionProvider().getSelection());
	}
	
	private void updateFilter() {
		this.inputUpdater.schedule();
	}
	
	private void clearActionInfo() {
		this.actionUtil.getStatusLine().clearAll();
	}
	
	private void updateSelectionInfo(final ITreeSelection selection) {
		if (this.isUpdating) {
			return;
		}
		final Object infoObject= null;
		final String message= null;
		
//		if (tool != null && !selection.isEmpty()) {
//			if (selection.size() == 1) {
//				final TreePath treePath= selection.getPaths()[0];
//				final IElementName elementName= getFQElementName(treePath);
//				final String name= (elementName != null) ? elementName.getDisplayName() : null;
//				if (name != null) {
//					infoObject= selection.getFirstElement();
//					message= name;
//				}
//			}
//			else {
//				message= NLS.bind("{0} items selected", selection.size());
//			}
//			if (message != null) {
//				message= NLS.bind("{0}  \u2012  {1}", message, tool.getLabel(ITool.DEFAULT_LABEL)); //$NON-NLS-1$
//			}
//		}
		
		if (infoObject == null || !infoObject.equals(this.currentInfoObject)) {
			clearActionInfo();
		}
		this.currentInfoObject= infoObject;
		this.actionUtil.getStatusLine().setSelectionMessage(
				(message != null) ? new StatusInfo(IStatus.OK, message) : null );
	}
	
	
	@Override
	public @Nullable RProcess getTool() {
		return this.process;
	}
	
	@Override
	public void addToolListener(final ActiveToolListener action) {
		this.toolListeners.add(action);
	}
	
	@Override
	public void removeToolListener(final ActiveToolListener action) {
		this.toolListeners.remove(action);
	}
	
	/** UI thread only */
	private void setTool(final @Nullable Tool tool, final boolean update) {
		final RProcess process= (tool != null
						&& tool.isProvidingFeatureSet(RConsoleTool.R_DATA_FEATURESET_ID)
						&& !tool.isTerminated() ) ?
				(RProcess) tool : null;
		if (this.process == tool) {
			return;
		}
		final RProcess oldProcess= process;
		synchronized (this.sourceLock) {
			this.process= process;
		}
		
		final ActiveToolEvent event= new ActiveToolEvent(ActiveToolEvent.TOOL_ACTIVATED, process);
		for (final ActiveToolListener listener : this.toolListeners) {
			listener.onToolChanged(event);
		}
		
		setApp((process != null) ? AppRegistry.getInstance().getApp(process) : null, update);
	}
	
	public @Nullable RApp getApp() {
		return this.app;
	}
	
	/** UI thread only */
	private void setApp(@Nullable RApp app, final boolean update) {
		if (app != null && app.getVariables() == null) {
			app= null;
		}
		if (this.app == app) {
			return;
		}
		
		final RApp oldApp= this.app;
		if (oldApp != null) {
			oldApp.removeListener(this.inputUpdater);
		}
		synchronized (this.sourceLock) {
			this.app= app;
		}
		clearActionInfo();
		
		this.inputUpdater.forceUpdate(app);
		if (app != null) {
			setContentDescription(computeContentDescription(app));
			app.addListener(this.inputUpdater);
		}
		else {
			setContentDescription("No app at this time.");
		}
		if (update) {
			this.inputUpdater.schedule();
			
			if (app == null && oldApp == this.shownByLauncher) {
				Display.getCurrent().timerExec(200, () -> {
					showPreviousView(oldApp);
				});
			}
		}
	}
	
	private String computeContentDescription(final RApp app) {
		final StringBuilder sb= new StringBuilder();
		
		final VariablesData vars= app.getVariables();
		if (vars != null) {
			sb.append(vars.getExpression());
		}
		else {
			sb.append("<no available>");
		}
		
		final IResource resource= app.getResource();
		if (resource != null) {
			if (sb.length() > 0) {
				sb.append("\u2002\u2013\u2002"); //$NON-NLS-1$
			}
			sb.append(resource.getFullPath().toString());
		}
		
		return sb.toString();
	}
	
	
	public boolean getFilterIncludeInternal() {
		return this.filterIncludeInternal;
	}
	
	public String getFilterSearchText() {
		return this.filterText;
	}
	
	
	public void setShownByLauncher(final RApp app) {
		this.shownByLauncher= app;
	}
	
	private void showPreviousView(final RApp oldApp) {
		if (this.app == null && oldApp == this.shownByLauncher) {
			final IWorkbenchPage page= getSite().getPage();
			final IViewPart[] viewStack= page.getViewStack(this);
			if (viewStack != null && viewStack.length >= 2 && viewStack[0] == this) {
				page.bringToTop(viewStack[1]);
			}
		}
	}
	
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(final Class<T> adapterType) {
		if (adapterType == Control.class) {
			return (T) this.treeViewer.getTree();
		}
		if (adapterType == Tool.class) {
			return (T) this.process;
		}
		return super.getAdapter(adapterType);
	}
	
}
