/*=============================================================================#
 # Copyright (c) 2008, 2017 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.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;

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

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.IContentAssistComputer;


public class RoxygenCompletionComputer implements IContentAssistComputer {
	
	
	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 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 RKeywordCompletionProposal {
		
		
		public TagProposal(final AssistInvocationContext context, final String keyword, final int replacementOffset) {
			super(context, keyword, replacementOffset);
		}
		
		
		@Override
		public Image getImage() {
			return LTKUI.getImages().get(LTKUI.OBJ_TEXT_AT_TAG_IMAGE_ID);
		}
		
		@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
		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 SourceViewer viewer= context.getSourceViewer();
			final IDocument document= viewer.getDocument();
			try {
				String replacementString= getReplacementString();
				final int newCaretOffset= replacementOffset+replacementString.length()+1;
				if (replacementOffset+replacementLength == document.getLength() || document.getChar(replacementOffset+replacementLength) != ' ') {
					replacementString= replacementString + ' ';
				}
				document.replace(replacementOffset, replacementLength, replacementString);
				setCursorPosition(newCaretOffset);
			}
			catch (final BadLocationException e) {
			}
		}
		
	}
	
	
	public RoxygenCompletionComputer() {
	}
	
	
	@Override
	public void sessionStarted(final ISourceEditor editor, final ContentAssist assist) {
	}
	
	@Override
	public void sessionEnded() {
	}
	
	@Override
	public IStatus 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);
		}
		
		return Status.OK_STATUS;
	}
	
	@Override
	public IStatus computeInformationProposals(final AssistInvocationContext context,
			final AssistProposalCollector proposals, final IProgressMonitor monitor) {
		return null;
	}
	
	
	private 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 int offset= context.getInvocationOffset() - prefix.length();
		final List<String> keywords= TAG_COMMANDS;
		for (final String keyword : keywords) {
			if (keyword.regionMatches(true, 0, prefix, 0, prefix.length())) {
				proposals.add(new TagProposal(context, keyword, offset));
			}
		}
	}
	
}
