/*=============================================================================#
 # Copyright (c) 2010, 2020 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.ui.rhelp;

import java.net.URI;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.IInformationControlCreator;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.InterruptNullProgressMonitor;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.status.eplatform.EStatusUtils;

import org.eclipse.statet.ltk.ast.core.util.AstSelection;
import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
import org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.model.IRSourceUnit;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.rsource.ast.FCall;
import org.eclipse.statet.r.core.rsource.ast.NodeType;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.rhelp.core.REnvHelp;
import org.eclipse.statet.rhelp.core.RPkgHelp;


@NonNullByDefault
public class RHelpHover implements InfoHover {
	
	
	private final int mode;
	
	private @Nullable IInformationControlCreator controlCreator;
	
	
	public RHelpHover() {
		this(MODE_TOOLTIP);
	}
	
	public RHelpHover(final int mode) {
		this.mode= mode;
	}
	
	
	@Override
	public @Nullable Object getHoverInfo(final AssistInvocationContext context,
			final ProgressMonitor m) throws StatusException {
		m.beginSubTask("Looking up R help...");
		
		final AstSelection astSelection= context.getAstSelection();
		if (!(astSelection.getCovering() instanceof RAstNode)) {
			return null;
		}
		final IRSourceUnit rSourceUnit= (context.getSourceUnit() instanceof IRSourceUnit) ?
				(IRSourceUnit) context.getSourceUnit() : null;
		
		final RAstNode rNode= (RAstNode) astSelection.getCovering();
		RElementName name= RHelpLtkUI.searchName(rNode, context, true);
		if ((this.mode & MODE_FOCUS) != 0 && name == null) {
			RAstNode parent;
			switch (rNode.getNodeType()) {
			case SYMBOL:
			case STRING_CONST:
				parent= rNode.getRParent();
				if (parent != null && parent.getNodeType() == NodeType.F_CALL_ARG
						&& ((FCall.Arg) parent).getNameChild() == rNode) {
					name= RHelpLtkUI.searchNameOfFunction(parent, context);
				}
				break;
			case F_CALL:
			case F_CALL_ARGS:
			case F_CALL_ARG:
				name= RHelpLtkUI.searchNameOfFunction(rNode, context);
				break;
			default:
				break;
			}
		}
		if (name == null || m.isCanceled()) {
			return null;
		}
		
		final REnvHelp help;
		Object helpObject= null;
		try {
			help= RHelpLtkUI.getEnvHelp(rSourceUnit);
		}
		catch (final StatusException e) {
			return false;
		}
		try {
			if (RElementName.isPackageFacetScopeType(name.getType())) {
				helpObject= help.getPkgHelp(name.getSegmentName());
			}
			else {
				if (name.getScope() != null
						&& RElementName.isPackageFacetScopeType(name.getScope().getType()) ) {
					final RPkgHelp pkgHelp= help.getPkgHelp(name.getScope().getSegmentName());
					if (pkgHelp != null) {
						helpObject= pkgHelp.getPageForTopic(name.getSegmentName());
					}
				}
				if (helpObject== null) {
					helpObject= RHelpLtkUI.searchTopicObject1(help, name.getSegmentName(),
							(RAstNode) astSelection.getCovering(), rSourceUnit );
					if (helpObject == null && !m.isCanceled()) {
						helpObject= (m instanceof InterruptNullProgressMonitor) ?
								doSearch2Safe(help, name.getSegmentName(), m) :
								RHelpLtkUI.searchTopicObject2(help, name.getSegmentName(), m);
					}
				}
			}
		}
		catch (final CoreException e) {
			// CANCELLED
			return null;
		}
		finally {
			help.unlock();
		}
		if (helpObject == null || m.isCanceled()) {
			return null;
		}
		
		final URI httpUrl= RCore.getRHelpHttpService().toHttpUrl(helpObject,
				RHelpLtkUI.INFO_TARGET );
		if (httpUrl != null) {
			return new RHelpInfoHoverCreator.Data(context.getSourceViewer().getTextWidget(),
					helpObject, httpUrl);
		}
		return null;
	}
	
	/** Runs search in separate job to avoid interrupted thread in lucene */
	private @Nullable Object doSearch2Safe(final REnvHelp help, final String topic, final ProgressMonitor m) {
		class SafeJob extends Job {
			Object helpObject;
			public SafeJob() {
				super(String.format("Lookup R Help for '%1$s'", topic));
				setPriority(Job.SHORT);
				setUser(false);
			}
			@Override
			protected IStatus run(final IProgressMonitor monitor) {
				final ProgressMonitor m= EStatusUtils.convert(monitor);
				try {
					this.helpObject= RHelpLtkUI.searchTopicObject2(help, topic, m);
					return Status.OK_STATUS;
				}
				catch (final StatusException e) {
					return Status.CANCEL_STATUS;
				}
			}
		}
		final SafeJob job= new SafeJob();
		job.schedule();
		while (true) {
			try {
				job.join();
				return job.helpObject;
			}
			catch (final InterruptedException e) {
				m.setCanceled(true);
			}
			if (m.isCanceled()) {
				if (job.cancel()) {
					return null;
				}
			}
		}
	}
	
	@Override
	public IInformationControlCreator getHoverControlCreator() {
		IInformationControlCreator controlCreator= this.controlCreator;
		if (controlCreator == null) {
			controlCreator= new RHelpInfoHoverCreator(this.mode);
			this.controlCreator= controlCreator;
		}
		return controlCreator;
	}
	
}
