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

import java.util.concurrent.TimeUnit;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;

import org.eclipse.statet.jcommons.collections.ImList;

import org.eclipse.statet.ecommons.text.core.FragmentDocument;
import org.eclipse.statet.ecommons.text.core.PartitionConstraint;

import org.eclipse.statet.internal.r.ui.editors.RContextInformationValidator;
import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
import org.eclipse.statet.ltk.ui.sourceediting.assist.ContentAssist;
import org.eclipse.statet.ltk.ui.sourceediting.assist.ContentAssistComputerRegistry;
import org.eclipse.statet.ltk.ui.sourceediting.assist.ContentAssistProcessor;
import org.eclipse.statet.r.console.core.util.LoadReferencesUtil;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.source.IRDocumentConstants;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;
import org.eclipse.statet.r.ui.editors.IRSourceEditor;


public class RContentAssistProcessor extends ContentAssistProcessor {
	
	
	private static PartitionConstraint NO_R_COMMENT_CONSTRAINT = new PartitionConstraint() {
		@Override
		public boolean matches(final String partitionType) {
			return (partitionType != IRDocumentConstants.R_COMMENT_CONTENT_TYPE);
		}
	};
	
	
	private class Context extends RAssistInvocationContext {
		
		
		public Context(final int offset, final boolean isProposal,
				final IProgressMonitor monitor) {
			super((IRSourceEditor) RContentAssistProcessor.this.getEditor(),
					offset, getContentType(),
					isProposal,
					RContentAssistProcessor.this.scanner,
					monitor );
		}
		
		
		@Override
		protected int getToolReferencesWaitTimeout() {
			return (getAssistant().isCompletionProposalAutoRequest() ?
					LoadReferencesUtil.MAX_AUTO_WAIT : LoadReferencesUtil.MAX_EXPLICITE_WAIT );
		}
		
		@Override
		protected void toolReferencesResolved(final ImList<CombinedRElement> resolvedElements) {
			reloadPossibleCompletions(this);
		}
		
	}
	
	
	private final RHeuristicTokenScanner scanner;
	
	private int timeoutCounter;
	
	
	public RContentAssistProcessor(final ContentAssist assistant, final String partition, 
			final ContentAssistComputerRegistry registry, final IRSourceEditor editor) {
		super(assistant, partition, registry, editor);
		this.scanner= RHeuristicTokenScanner.create(editor.getDocumentContentInfo());
	}
	
	
	@Override
	protected AssistInvocationContext createCompletionProposalContext(final int offset,
			final IProgressMonitor monitor) {
		return new Context(offset, true, monitor);
	}
	
	@Override
	protected AssistInvocationContext createContextInformationContext(final int offset,
			final IProgressMonitor monitor) {
		final Context context;
		if (this.timeoutCounter <= 3) {
			final long startTime= System.nanoTime();
			
			context= new Context(offset, true, monitor);
			
			if (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) > 50) {
				this.timeoutCounter= Math.min(this.timeoutCounter + 1, 10);
			}
			else {
				this.timeoutCounter= Math.max(this.timeoutCounter - 1, 0);
			}
		}
		else {
			context= new Context(offset, false, monitor);
		}
		return context;
	}
	
	
	@Override
	protected IContextInformationValidator createContextInformationValidator() {
		return new RContextInformationValidator();
	}
	
	@Override
	protected boolean forceContextInformation(final AssistInvocationContext context) {
		try {
			int offset = context.getInvocationOffset();
			if (context.getIdentifierPrefix().length() > 0 
					|| this.scanner == null) {
				return false;
			}
			IDocument document = context.getSourceViewer().getDocument();
			if (document instanceof FragmentDocument) {
				final FragmentDocument inputDoc = (FragmentDocument) document;
				document = inputDoc.getMasterDocument();
				offset = offset + inputDoc.getOffsetInMasterDocument();
			}
			if (offset < 2) {
				return false;
			}
			this.scanner.configure(document, NO_R_COMMENT_CONSTRAINT);
			final int previousOffset = this.scanner.findNonBlankBackward(offset, RHeuristicTokenScanner.UNBOUND, true);
			if (previousOffset > 0) {
				final char c = document.getChar(previousOffset);
				if (c == '(' || c == ',') {
					final String partitionType = this.scanner.getPartition(previousOffset).getType();
					return (IRDocumentConstants.R_DEFAULT_CONTENT_CONSTRAINT.matches(partitionType));
				}
			}
		}
		catch (final BadLocationException e) {}
		
		return false;
	}
	
}
