/*=============================================================================#
 # 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.ltk.ui.sourceediting;

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TypedRegion;
import org.eclipse.jface.text.information.IInformationProvider;
import org.eclipse.jface.text.information.IInformationProviderExtension;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.collections.ImList;
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.ecommons.text.core.util.TextUtils;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
import org.eclipse.statet.ltk.ui.sourceediting.assist.InfoHover;


@NonNullByDefault
public abstract class EditorInformationProvider
		implements IInformationProvider, IInformationProviderExtension, IInformationProviderExtension2 {
	
	
	private final ISourceEditor editor;
	
	private final ImList<? extends InfoHover> hovers;
	
	private volatile @Nullable InfoHover bestHover;
	
	
	public EditorInformationProvider(final ISourceEditor editor,
			final ImList<? extends InfoHover> hovers) {
		this.editor= editor;
		this.hovers= hovers;
	}
	
	
	public ISourceEditor getEditor() {
		return this.editor;
	}
	
	@Override
	public @Nullable String getInformation(final ITextViewer textViewer, final IRegion region) {
		return null;
	}
	
	@Override
	public @Nullable Object getInformation2(final ITextViewer textViewer, final IRegion region) {
		this.bestHover= null;
		try {
			final String contentType= (region instanceof TypedRegion) ?
					((TypedRegion) region).getType() :
					TextUtils.getContentType(this.editor.getViewer().getDocument(),
							this.editor.getDocumentContentInfo(), region.getOffset(),
							region.getLength() == 0 );
			
			final AssistInvocationContext context= createContext(region, contentType,
					new NullProgressMonitor() );
			if (context != null) {
				try {
					final AtomicReference<Object> info= new AtomicReference<>();
					if (Display.getCurrent() != null) {
						try {
							final IProgressService progressService= this.editor.getServiceLocator().getService(IProgressService.class);
							progressService.run(true, true, new IRunnableWithProgress() {
								@Override
								public void run(final IProgressMonitor monitor)
										throws InvocationTargetException, InterruptedException {
									final ProgressMonitor m= EStatusUtils.convert(monitor);
									try {
										getInfo0(context, info, m);
									}
									catch (final StatusException e) {
										throw new InvocationTargetException(e);
									}
								}
							});
						}
						catch (final InvocationTargetException e) {
							throw (StatusException) e.getCause();
						}
					}
					else {
						getInfo0(context, info, new InterruptNullProgressMonitor());
					}
					return info.get();
				}
				catch (final InterruptedException e) {
					return null;
				}
				catch (final StatusException e) {
					return null;
				}
			}
		}
		catch (final Exception e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, LTKUIPlugin.BUNDLE_ID,
					"An error occurred when preparing the information hover (command).", e ));
		}
		return null;
	}
	
	protected abstract @Nullable AssistInvocationContext createContext(IRegion region, String contentType,
			IProgressMonitor monitor );
	
	private void getInfo0(final AssistInvocationContext context,
			final AtomicReference<Object> infoValue,
			final ProgressMonitor m) throws StatusException {
		for (int i= 0; i < this.hovers.size(); i++) {
			m.setWorkRemaining(this.hovers.size() - i);
			if (m.isCanceled()) {
				return;
			}
			try {
				final InfoHover hover= this.hovers.get(i);
				final Object info= hover.getHoverInfo(context, m.newSubMonitor(1));
				if (info != null) {
					this.bestHover= hover;
					infoValue.set(info);
					return;
				}
			}
			catch (final StatusException e) {
				if (e.getStatus().getSeverity() == Status.CANCEL) {
					return;
				}
			}
		}
	}
	
	
	@Override
	public @Nullable IInformationControlCreator getInformationPresenterControlCreator() {
		final InfoHover hover= this.bestHover;
		if (hover != null) {
			return hover.getHoverControlCreator();
		}
		return null;
	}
	
}
