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

import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;

import org.eclipse.statet.jcommons.text.core.input.OffsetStringParserInput;

import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistCompletionInformationProposalWrapper;
import org.eclipse.statet.r.core.model.ArgsDefinition;
import org.eclipse.statet.r.core.rsource.ast.FCall;
import org.eclipse.statet.r.core.rsource.ast.FCall.Args;
import org.eclipse.statet.r.core.rsource.ast.RAst;
import org.eclipse.statet.r.core.rsource.ast.RAst.FCallArgMatch;
import org.eclipse.statet.r.core.rsource.ast.RScanner;


public class RContextInformationValidator implements IContextInformationValidator, IContextInformationPresenter {
	
	
	private ITextViewer fViewer;
	private int fStartOffset;
	
	private IContextInformation fInfo;
	
	private RArgumentListContextInformation fArgInfo;
	private int fCurrentParameter;
//	private RScanner scanner;
	private long fScannedArgsStamp;
	private Args fScannedArgs;
	
	private int fLastPresentation = -2;
	
	
	public RContextInformationValidator() {
	}
	
	
	@Override
	public boolean isContextInformationValid(final int offset) {
		if (fInfo == null) {
			return false;
		}
		final IDocument document = fViewer.getDocument();
		if (offset < fStartOffset || offset > document.getLength()) {
			return false;
		}
		if (fArgInfo != null) {
			final Args args = getScannedArgs();
			if (args != null) {
				return (offset <= args.getEndOffset());
			}
		}
		return (offset == fStartOffset);
	}
	
	@Override
	public void install(IContextInformation info, final ITextViewer viewer, final int offset) {
		if (info instanceof AssistCompletionInformationProposalWrapper) {
			info= ((AssistCompletionInformationProposalWrapper) info).getContextInformation();
		}
		
		fScannedArgs = null;
		fLastPresentation = -2;
		if (info instanceof RArgumentListContextInformation) {
			fInfo = fArgInfo = (RArgumentListContextInformation) info;
			fCurrentParameter = -1;
		}
		else {
			fInfo = info;
			fArgInfo = null;
			return;
		}
		fViewer = viewer;
		fStartOffset = offset;
	}
	
	@Override
	public boolean updatePresentation(final int offset, final TextPresentation presentation) {
		if (fArgInfo != null) {
			final ArgsDefinition args = fArgInfo.getArguments();
			if (args != null && args.size() > 0) {
				final int argIndex = getCurrentArgInFDef(offset);
				final int[] idxs = fArgInfo.getInformationDisplayStringArgumentIdxs();
				if (argIndex >= 0 && argIndex < idxs.length) {
					if (argIndex == fLastPresentation) {
						return false;
					}
					final int start = idxs[argIndex];
					final int stop = (argIndex+1 < idxs.length) ? idxs[argIndex+1] : fArgInfo.getInformationDisplayString().length();
					presentation.clear();
					presentation.addStyleRange(new StyleRange(start, stop-start, null, null, SWT.BOLD));
					fLastPresentation = argIndex;
					return true;
				}
			}
		}
		if (fLastPresentation == -1) {
			return false;
		}
		presentation.clear();
		presentation.addStyleRange(new StyleRange(0, fInfo.getInformationDisplayString().length(),
				null, null, SWT.NORMAL));
		fLastPresentation = -1;
		return true;
	}
	
	private FCall.Args getScannedArgs() {
		final AbstractDocument document = (AbstractDocument) fViewer.getDocument();
		final long stamp = document.getModificationStamp();
		if (fScannedArgs == null || fScannedArgsStamp != stamp) {
			try {
				final String text= document.get(fStartOffset, Math.min(0x800, document.getLength() - fStartOffset));
				final RScanner scanner= new RScanner(AstInfo.LEVEL_MODEL_DEFAULT);
				fScannedArgs= scanner.scanFCallArgs(
						new OffsetStringParserInput(text, fStartOffset)
								.init(fStartOffset, fStartOffset + text.length()),
						true );
				fScannedArgsStamp = stamp;
			}
			catch (final Exception e) {
				fScannedArgs = null;
			}
		}
		
		return fScannedArgs;
	}
	
	private int getCurrentArgInFDef(final int offset) {
		final int callArgIdx= getCurrentArgInFCall(offset);
		if (callArgIdx >= 0) {
			final FCallArgMatch match= RAst.matchArgs(getScannedArgs(), fArgInfo.getArguments());
			final ArgsDefinition.Arg argDef= match.getArgDef(callArgIdx);
			if (argDef != null) {
				return argDef.index;
			}
		}
		return -1;
	}
	
	private int getCurrentArgInFCall(final int offset) {
		final Args args = getScannedArgs();
		if (args != null) {
			final int last = args.getChildCount()-1;
			if (last == -1) {
				return 0;
			}
			for (int i = 0; i < last; i++) {
				if (offset <= args.getSeparatorOffset(i)) {
					return i;
				}
			}
			return last;
		}
		return -1;
	}
	
}
