/*=============================================================================#
 # Copyright (c) 2009, 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.ltk.ui.sourceediting.assist;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ContentAssistEvent;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ICompletionListener;
import org.eclipse.jface.text.contentassist.ICompletionListenerExtension;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.ui.SharedMessages;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;


/**
 * LTK content assistant.
 */
@NonNullByDefault
public class ContentAssist extends ContentAssistant {
	
	
	private static final int ON=                            1 << 0;
	
	private static final int AUTO_REQUEST=                  1 << 3;
	
	private static final int SPECIFIC_SESSION=              1 << 5;
	
	private static final int RELOAD_REQUEST=                1 << 6;
	
	
	abstract static class Processor implements IContentAssistProcessor {
		
		
		private final ContentAssist assist;
		
		private final String contentType;
		
		
		public Processor(final ContentAssist assist, final String contentType) {
			assert (assist != null);
			assert (contentType != null);
			
			this.assist= assist;
			
			this.contentType= contentType;
		}
		
		
		public final ContentAssist getAssistant() {
			return this.assist;
		}
		
		public final String getContentType() {
			return this.contentType;
		}
		
		@Override
		public final ICompletionProposal @Nullable [] computeCompletionProposals(
				final ITextViewer viewer, final int offset) {
			this.assist.onCompletionProposalComputeBegin(getContentType());
			try {
				return doComputeCompletionProposals(viewer, offset);
			}
			finally {
				this.assist.onCompletionProposalComputeEnd(getContentType());
			}
		}
		
		protected abstract ICompletionProposal @Nullable [] doComputeCompletionProposals(
				final ITextViewer viewer, final int offset);
		
		@Override
		public final IContextInformation @Nullable [] computeContextInformation(
				final ITextViewer viewer, final int offset) {
			this.assist.onContextInformationComputeBegin(getContentType());
			try {
				return doComputeContextInformation(viewer, offset);
			}
			finally {
				this.assist.onContextInformationComputeEnd(getContentType());
			}
		}
		
		protected abstract IContextInformation @Nullable [] doComputeContextInformation(
				final ITextViewer viewer, final int offset);
		
	}
	
	private static class WrappedProcessor extends Processor {
		
		
		private final IContentAssistProcessor processor;
		
		
		public WrappedProcessor(final ContentAssist assist, final String contentType,
				final IContentAssistProcessor processor) {
			super(assist, contentType);
			this.processor= processor;
		}
		
		
		@Override
		public char @Nullable [] getCompletionProposalAutoActivationCharacters() {
			return this.processor.getCompletionProposalAutoActivationCharacters();
		}
		
		@Override
		public char @Nullable [] getContextInformationAutoActivationCharacters() {
			return this.processor.getContextInformationAutoActivationCharacters();
		}
		
		@Override
		protected ICompletionProposal @Nullable [] doComputeCompletionProposals(
				final ITextViewer viewer, final int offset) {
			return this.processor.computeCompletionProposals(viewer, offset);
		}
		
		@Override
		protected IContextInformation @Nullable [] doComputeContextInformation(final ITextViewer viewer,
				final int offset) {
			return this.processor.computeContextInformation(viewer, offset);
		}
		
		@Override
		public @Nullable String getErrorMessage() {
			return this.processor.getErrorMessage();
		}
		
		@Override
		public @Nullable IContextInformationValidator getContextInformationValidator() {
			return this.processor.getContextInformationValidator();
		}
		
	}
	
	
	private class SelfListener implements ICompletionListener, ICompletionListenerExtension {
		
		
		@Override
		public void assistSessionStarted(final ContentAssistEvent event) {
			onCompletionProposalSessionBegin(event.isAutoActivated);
		}
		
		@Override
		public void assistSessionRestarted(final ContentAssistEvent event) {
		}
		
		@Override
		public void assistSessionEnded(final ContentAssistEvent event) {
			onCompletionProposalSessionEnd();
		}
		
		@Override
		public void selectionChanged(final @Nullable ICompletionProposal proposal,
				final boolean smartToggle) {
			if (proposal != ContentAssist.this.completionProposalSelection) {
				ContentAssist.this.completionProposalSelection= proposal;
				ContentAssist.this.completionProposalSelectionCounter++;
			}
		}
		
	}
	
	
	private boolean isAutoInsertEnabled;
	private boolean isAutoInsertOverwritten;
	
	private boolean isRepeatedInvocationModeEnabled;
	
	private int completionProposalSessionRequest;
	private int completionProposalSession;
	private int completionProposalSessionCounter;
	
	private String specificCategoryId;
	
	private @Nullable ICompletionProposal completionProposalSelection;
	private int completionProposalSelectionCounter;
	
	private @Nullable KeySequence completionProposalKeyBinding;
	private @Nullable String completionProposalIterationGesture;
	
	private int contextInformationSession;
	
	private boolean showSubstringMatchesEnabled;
	
	
	public ContentAssist() {
		addCompletionListener(new SelfListener());
	}
	
	
	boolean isProposalPopupActive1() {
		return super.isProposalPopupActive();
	}
	
	boolean isContextInfoPopupActive1() {
		return super.isContextInfoPopupActive();
	}
	
	public void hidePopups() {
		hide();
	}
	
	@Override
	protected void hide() {
		// Workaround for bug 94106 (-> loop) and bug 512251 (-> catch exception) in Platform Text
		try {
			super.hide();
		}
		catch (final RuntimeException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, LTKUIPlugin.BUNDLE_ID,
					"An error occurred when hiding content assistant.", e ));
		}
		
		for (int counter= 0; counter < 100 && isContextInfoPopupActive(); counter++) {
			try {
				super.hide();
			}
			catch (final RuntimeException e) {}
		}
	}
	
	
	private void onCompletionProposalSessionBegin(final boolean isAutoActivated) {
		this.completionProposalSession= (this.completionProposalSessionRequest != 0) ?
				ContentAssist.this.completionProposalSessionRequest :
				(isAutoActivated) ? (ON | AUTO_REQUEST) : (ON);
		this.completionProposalSessionRequest= 0;
		
		this.completionProposalSessionCounter++;
		
		this.completionProposalSelectionCounter= 0;
		
		this.completionProposalKeyBinding= WorkbenchUIUtils.getBestKeyBinding(
				ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS );
		setRepeatedInvocationTrigger(this.completionProposalKeyBinding);
		this.completionProposalIterationGesture= (this.completionProposalKeyBinding != null) ?
				NLS.bind(SharedMessages.Affordance_Press_message, this.completionProposalKeyBinding.format()) :
				SharedMessages.Affordance_Click_message;
	}
	
	private void onCompletionProposalComputeBegin(final String contentType) {
		this.completionProposalSessionCounter= 0;
		this.completionProposalSelection= null;
	}
	
	private void onCompletionProposalComputeEnd(final String contentType) {
		this.completionProposalSession&= ~AUTO_REQUEST;
	}
	
	private void onCompletionProposalSessionEnd() {
		this.completionProposalSession= 0;
		
		this.completionProposalSelection= null;
		
		this.completionProposalKeyBinding= null;
		this.completionProposalIterationGesture= null;
	}
	
	private void onContextInformationComputeBegin(final String contentType) {
		if (this.contextInformationSession == 0) {
			this.contextInformationSession= (ON | AUTO_REQUEST);
		}
	}
	
	private void onContextInformationComputeEnd(final String contentType) {
		this.contextInformationSession= 0;
	}
	
	
	@Override
	public void setContentAssistProcessor(@Nullable IContentAssistProcessor processor,
			final String contentType) {
		if (contentType == null) {
			throw new NullPointerException("contentType"); //$NON-NLS-1$
		}
		if (processor != null && !(processor instanceof Processor)) {
			processor= new WrappedProcessor(this, contentType, processor);
		}
		super.setContentAssistProcessor(processor, contentType);
	}
	
	@Override
	public void enableAutoInsert(final boolean enabled) {
		this.isAutoInsertEnabled= enabled;
		if (!this.isAutoInsertOverwritten) {
			super.enableAutoInsert(enabled);
		}
	}
	
	@Override
	public void setRepeatedInvocationMode(final boolean cycling) {
		this.isRepeatedInvocationModeEnabled= cycling;
		super.setRepeatedInvocationMode(cycling);
	}
	
	/**
	 * Overwrites the current (user) setting temporarily and enables auto insert until it is reset
	 * by calling {@link #enableAutoInsertSetting()}.
	 * 
	 * @see #enableAutoInsert(boolean)
	 */
	void enableAutoInsertTemporarily() {
		this.isAutoInsertOverwritten= true;
		super.enableAutoInsert(true);
	}
	
	/**
	 * Disables the overwriting of auto insert enabled by {@link #enableAutoInsertTemporarily()}
	 * and resets it to the (user) setting.
	 * 
	 * @see #enableAutoInsert(boolean)
	 */
	void enableAutoInsertSetting() {
		if (this.isAutoInsertOverwritten) {
			this.isAutoInsertOverwritten= false;
			super.enableAutoInsert(this.isAutoInsertEnabled);
		}
	}
	
	
	public void showPossibleCompletions(final boolean restart, final boolean autostart) {
		class AutoAssist extends AutoAssistListener {
			
			public static final int SHOW_PROPOSALS= 1;
			
			@Override
			public void start(final int showStyle) {
				showAssist(showStyle);
			}
			
		}
		
		if (restart) {
			super.hide();
		}
		if (autostart) {
			new AutoAssist().start(AutoAssist.SHOW_PROPOSALS);
		}
		else {
			super.showPossibleCompletions();
		}
	}
	
	@Override
	public @Nullable String showPossibleCompletions() {
		this.completionProposalSessionRequest= (ON);
		try {
			return super.showPossibleCompletions();
		}
		finally {
			this.completionProposalSessionRequest= 0;
		}
	}
	
	public @Nullable String showPossibleCompletions(final String categoryId) {
		if (categoryId == null) {
			throw new NullPointerException("categoryId"); //$NON-NLS-1$
		}
		this.completionProposalSessionRequest= (ON | SPECIFIC_SESSION);
		this.specificCategoryId= categoryId;
		try {
			return super.showPossibleCompletions();
		}
		finally {
			this.completionProposalSessionRequest= 0;
		}
	}
	
	void reloadPossibleCompletions() {
		if (this.completionProposalSession == 0
				|| (isCompletionProposalAutoRequest() && !isProposalPopupActive1())) {
			return;
		}
		
		this.completionProposalSession|= RELOAD_REQUEST;
		this.completionProposalSessionRequest= this.completionProposalSession;
		super.setRepeatedInvocationMode(true); // avoid start of new session
		try {
			super.showPossibleCompletions();
		}
		finally {
			this.completionProposalSession&= ~RELOAD_REQUEST;
			this.completionProposalSessionRequest= 0;
			super.setRepeatedInvocationMode(this.isRepeatedInvocationModeEnabled);
		}
	}
	
	public final boolean isCompletionProposalAutoRequest() {
		return ((this.completionProposalSession & AUTO_REQUEST) != 0);
	}
	
	final boolean isCompletionProposalReloadRequest() {
		return ((this.completionProposalSession & RELOAD_REQUEST) != 0);
	}
	
	public final boolean isCompletionProposalSpecificSession() {
		return ((this.completionProposalSession & SPECIFIC_SESSION) != 0);
	}
	
	public final @Nullable String getSpecificMode() {
		return (isCompletionProposalSpecificSession()) ? this.specificCategoryId : null;
	}
	
	public final int getCompletionProposalSessionCounter() {
		return this.completionProposalSessionCounter;
	}
	
	public @Nullable KeySequence getCompletionProposalKeyBinding() {
		return this.completionProposalKeyBinding;
	}
	
	public @Nullable String getCompletionProposalIterationGesture() {
		return this.completionProposalIterationGesture;
	}
	
	public final int getCompletionProposalSelectionCounter() {
		return this.completionProposalSelectionCounter;
	}
	
	
	@Override
	public @Nullable String showContextInformation() {
		if (isCompletionProposalSpecificSession() && isProposalPopupActive()) {
			hide();
		}
		
		this.contextInformationSession= (ON);
		return super.showContextInformation();
	}
	
	public final boolean isContextInformationAutoRequest() {
		return ((this.contextInformationSession & AUTO_REQUEST) != 0);
	}
	
	
	public void setShowSubstringMatches(final boolean enabled) {
		this.showSubstringMatchesEnabled= enabled;
	}
	
	public boolean getShowSubstringMatches() {
		return this.showSubstringMatchesEnabled;
	}
	
}
