/*=============================================================================#
 # 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.internal.r.ui.editors;

import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.SearchPattern;

import org.eclipse.statet.ltk.ui.LTKUI;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistProposalCollector;
import org.eclipse.statet.ltk.ui.sourceediting.assist.ContentAssist;
import org.eclipse.statet.ltk.ui.sourceediting.assist.ContentAssistComputer;
import org.eclipse.statet.ltk.ui.sourceediting.assist.SimpleCompletionProposal;
import org.eclipse.statet.ltk.ui.sourceediting.assist.SourceProposal.ProposalParameters;


@NonNullByDefault
public class RoxygenCompletionComputer implements ContentAssistComputer {
	
	
	private static final List<String> TAG_COMMANDS;
	
	static {
		@SuppressWarnings("nls")
		final String[] tags= new String[] {
			"docType",
			"export",
			"exportClass",
			"exportMethod",
			"exportPattern",
			"import",
			"importFrom",
			"importClassesFrom",
			"importMethodsFrom",
			"name",
			"aliases",
			"title",
			"usage",
			"references",
			"note",
			"include",
			"slot",
			"param",
			"return",
			"returnType",
			"seealso",
			"example",
			"examples",
			"author",
			"concept",
			"keywords",
			"method",
			"prototype",
			"S3method", // deprecated 4.0
			"S3class",
			"listObject",
			"attributeObject",
			"environmentObject",
			"noRd",
			"useDynLib",
			"rdname", // 2.0
			"template", // 2.0
			"section", // 2.0
			"description", // 2.0
			"details", // 2.0
			"family", // 2.0
			"inheritParams", // 2.0
			"format", // 2.0
			"source", // 2.1
			"encoding", // 2.2
			"describeIn", // since 4.0
			"field", // since 4.0 (for fields of reference classes)
		};
		
		final String[] commands= new @NonNull String[tags.length];
		for (int i= 0; i < commands.length; i++) {
			commands[i]= '@' + tags[i];
		}
		TAG_COMMANDS= ImCollections.newList(commands);
	}
	
	private static class TagProposal extends SimpleCompletionProposal {
		
		
		public TagProposal(final ProposalParameters<?> parameters, final String keyword) {
			super(parameters, keyword);
		}
		
		
		@Override
		protected int computeReplacementLength(final int replacementOffset, final Point selection, final int caretOffset, final boolean overwrite) throws BadLocationException {
			int end= Math.max(caretOffset, selection.x + selection.y);
			if (overwrite) {
				final IDocument document= getInvocationContext().getSourceViewer().getDocument();
				while (end < document.getLength()) {
					if (Character.isLetterOrDigit(document.getChar(end))) {
						end++;
						continue;
					}
					break;
				}
			}
			return (end - replacementOffset);
		}
		
		
		@Override
		public Image getImage() {
			return LTKUI.getImages().get(LTKUI.OBJ_TEXT_AT_TAG_IMAGE_ID);
		}
		
		
		@Override
		public boolean isAutoInsertable() {
			return true;
		}
		
		@Override
		protected void doApply(final char trigger, final int stateMask, final int caretOffset,
				final int replacementOffset, final int replacementLength) throws BadLocationException {
			final AssistInvocationContext context= getInvocationContext();
			final IDocument document= context.getDocument();
			final ApplyData applyData= getApplyData();
			
			String replacement= getName();
			final int cursor= replacement.length() + 1;
			if (replacementOffset + replacementLength == document.getLength()
					|| document.getChar(replacementOffset + replacementLength) != ' ') {
				replacement= replacement + ' ';
			}
			
			document.replace(replacementOffset, replacementLength, replacement);
			
			applyData.setSelection(replacementOffset + cursor);
		}
		
	}
	
	
	private int searchMatchRules;
	
	
	public RoxygenCompletionComputer() {
	}
	
	
	@Override
	public void onSessionStarted(final ISourceEditor editor, final ContentAssist assist) {
		int matchRules= SearchPattern.PREFIX_MATCH;
		if (assist.getShowSubstringMatches()) {
			matchRules |= SearchPattern.SUBSTRING_MATCH;
		}
		this.searchMatchRules= matchRules;
	}
	
	@Override
	public void onSessionEnded() {
	}
	
	
	protected int getSearchMatchRules() {
		return this.searchMatchRules;
	}
	
	@Override
	public void computeCompletionProposals(final AssistInvocationContext context, final int mode,
			final AssistProposalCollector proposals, final IProgressMonitor monitor) {
		final String tagPrefix= getTagPrefix(context);
		if (tagPrefix != null) {
			doComputeTagProposals(context, tagPrefix, proposals, monitor);
		}
	}
	
	@Override
	public void computeInformationProposals(final AssistInvocationContext context,
			final AssistProposalCollector proposals, final IProgressMonitor monitor) {
	}
	
	
	private @Nullable String getTagPrefix(final AssistInvocationContext context) {
		try {
			final IDocument document= context.getSourceViewer().getDocument();
			final int start= Math.max(context.getInvocationOffset() - 20, 0); // max keyword length incl 
			final String s= document.get(start, context.getInvocationOffset()-start);
			final int last= s.length()-1;
			int i= last;
			while (i >= 0) {
				final char c= s.charAt(i);
				if (c == '@') {
					return s.substring(i);
				}
				if (!isRoxygenTagChar(c)) {
					return (i == last) ? "" : null; //$NON-NLS-1$
				}
				i--;
			}
			return null;
		}
		catch (final BadLocationException e) {
			return null;
		}
	}
	
	private boolean isRoxygenTagChar(final int c) {
		if ((c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A)) {
			return true;
		}
		final int type= Character.getType(c);
		return (type > 0) && (type < 12 || type > 19);
	}
	
	private void doComputeTagProposals(final AssistInvocationContext context, final String prefix,
			final AssistProposalCollector proposals, final IProgressMonitor monitor) {
		final ProposalParameters<?> parameters= new ProposalParameters<>(
				context, context.getInvocationOffset() - prefix.length(),
				new SearchPattern(getSearchMatchRules(), prefix) );
		
		final List<String> keywords= TAG_COMMANDS;
		for (final String keyword : keywords) {
			if (parameters.matchesNamePattern(keyword)) {
				proposals.add(new TagProposal(parameters, keyword));
			}
		}
	}
	
}
