/*=============================================================================#
 # 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 static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
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.ecommons.text.core.IFragmentDocument;
import org.eclipse.statet.ecommons.text.core.IPartitionConstraint;

import org.eclipse.statet.internal.r.ui.FCallNamePattern;
import org.eclipse.statet.internal.r.ui.editors.RElementCompletionProposal;
import org.eclipse.statet.internal.r.ui.editors.RElementCompletionProposal.RElementProposalParameters;
import org.eclipse.statet.internal.r.ui.editors.RHelpTopicCompletionProposal;
import org.eclipse.statet.internal.r.ui.editors.RPkgCompletionProposal;
import org.eclipse.statet.internal.r.ui.editors.RSimpleCompletionProposal;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.model.core.elements.IModelElement;
import org.eclipse.statet.ltk.ui.ElementLabelProvider;
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.AssistProposal;
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.SourceProposal.ProposalParameters;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.RSearchPattern;
import org.eclipse.statet.r.core.RSymbolComparator;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.ArgsDefinition;
import org.eclipse.statet.r.core.model.IRElement;
import org.eclipse.statet.r.core.model.IRFrame;
import org.eclipse.statet.r.core.model.IRFrameInSource;
import org.eclipse.statet.r.core.model.IRLangElement;
import org.eclipse.statet.r.core.model.IRMethod;
import org.eclipse.statet.r.core.model.RCoreFunctions;
import org.eclipse.statet.r.core.model.RElementAccess;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.pkgmanager.IRPkgManager;
import org.eclipse.statet.r.core.rlang.RTokens;
import org.eclipse.statet.r.core.rsource.ast.FCall;
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.RAstNode;
import org.eclipse.statet.r.core.source.IRDocumentConstants;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;
import org.eclipse.statet.r.ui.RLabelProvider;
import org.eclipse.statet.r.ui.sourceediting.RAssistInvocationContext.FCallInfo;
import org.eclipse.statet.r.ui.sourceediting.RFrameSearchPath.RFrameIterator;
import org.eclipse.statet.rhelp.core.REnvHelp;
import org.eclipse.statet.rhelp.core.RHelpManager;
import org.eclipse.statet.rhelp.core.RHelpTopicEntry;
import org.eclipse.statet.rhelp.core.RPkgHelp;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.RPkgBuilt;
import org.eclipse.statet.rj.renv.core.RPkgCompilation;
import org.eclipse.statet.rj.renv.runtime.RPkgManagerDataset;


@NonNullByDefault
public class RElementCompletionComputer implements ContentAssistComputer {
	
	
	private static final IPartitionConstraint NO_R_COMMENT_CONSTRAINT= new IPartitionConstraint() {
		@Override
		public boolean matches(final String partitionType) {
			return (partitionType != IRDocumentConstants.R_COMMENT_CONTENT_TYPE);
		};
	};
	
	
	private static final ImList<String> fgKeywords;
	static {
		final ArrayList<String> list= new ArrayList<>();
		Collections.addAll(list, RTokens.CONSTANT_WORDS);
		Collections.addAll(list, RTokens.FLOWCONTROL_WORDS);
		fgKeywords= ImCollections.toList(list, RSymbolComparator.R_NAMES_COLLATOR);
	}
	
	public static class CompleteRuntime extends RElementCompletionComputer {
		
		public CompleteRuntime() {
			super(RFrameSearchPath.ENGINE_MODE);
		}
		
	}
	
	
	protected static final int NA_PRIO= Integer.MIN_VALUE;
	
	protected static final int ARG_NAME_PRIO= 80;
	
	protected static final int ARG_TYPE_PRIO= 40;
	protected static final int ARG_TYPE_NO_PRIO= -40;
	
	
	private final ElementLabelProvider labelProvider= new RLabelProvider(RLabelProvider.NAMESPACE);
	
	private final int mode;
	
	private int searchMatchRules;
	
	private final RFrameSearchPath searchPath= new RFrameSearchPath();
	
	private boolean inDefault;
	private boolean inString;
	
	private int pkgNamePrio;
	private int helpTopicPrio;
	
	
	protected RElementCompletionComputer(final int mode) {
		this.mode= mode;
	}
	
	public RElementCompletionComputer() {
		this(0);
	}
	
	
	@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() {
		this.searchPath.clear();
	}
	
	
	protected final int getSearchMode(final RAssistInvocationContext context) {
		if (this.mode != 0) {
			return this.mode;
		}
		return context.getDefaultRFrameSearchMode();
	}
	
	protected int getSearchMatchRules() {
		return this.searchMatchRules;
	}
	
	
	protected final boolean isSymbolCandidate(final String name) {
		for (int i= 0; i < name.length(); i++) {
			if (RTokens.isRobustSeparator(name.charAt(i))) {
				return false;
			}
		}
		return true;
	}
	
	private boolean isCompletable(@Nullable RElementName elementName) {
		if (elementName == null) {
			return false;
		}
		do {
			switch (elementName.getType()) {
			case RElementName.SUB_INDEXED_S:
			case RElementName.SUB_INDEXED_D:
				return false;
			}
			if (elementName.getSegmentName() == null) {
				return false;
			}
			elementName= elementName.getNextSegment();
		}
		while (elementName != null);
		return true;
	}
	
	private @Nullable RAstNode getRAstNode(final RAssistInvocationContext context) {
		AstNode node= context.getInvocationAstSelection().getCovering();
		if (node == null) {
			node= context.getAstInfo().getRoot();
		}
		return (node instanceof RAstNode) ? (RAstNode) node : null;
	}
	
	
	@Override
	public void computeCompletionProposals(final AssistInvocationContext context,
			final int mode, final AssistProposalCollector proposals,
			final IProgressMonitor monitor) {
		if (context instanceof RAssistInvocationContext) {
			computeCompletionProposals((RAssistInvocationContext) context, mode, proposals,
					monitor );
		}
	}
	
	@Override
	public void computeInformationProposals(final AssistInvocationContext context,
			final AssistProposalCollector proposals, final IProgressMonitor monitor) {
		if (context instanceof RAssistInvocationContext) {
			doComputeContextProposals((RAssistInvocationContext) context, proposals, monitor);
		}
	}
	
	protected void computeCompletionProposals(final RAssistInvocationContext context, final int mode,
			final AssistProposalCollector proposals, final IProgressMonitor monitor) {
		if (context.getModelInfo() == null) {
			return;
		}
		
		// Get node
		final RAstNode node= getRAstNode(context);
		
		// Get prefix
		final RElementName prefixName= context.getIdentifierElementName();
		if (prefixName == null) {
			return;
		}
		
		this.inString= (context.getInvocationContentType() == IRDocumentConstants.R_STRING_CONTENT_TYPE);
		this.inDefault= !this.inString;
		
		this.pkgNamePrio= NA_PRIO;
		this.helpTopicPrio= NA_PRIO;
		
		if (prefixName.getNextSegment() == null) {
			final String help= checkHelp(context);
			if (help != null) {
				doComputeHelpTopicProposals(context, help, node, ARG_TYPE_PRIO, proposals);
				
				if (prefixName.getScope() == null) {
					doComputePkgNameProposals(context, ARG_TYPE_NO_PRIO, proposals);
				}
				return;
			}
			
			doComputeArgumentProposals(context, proposals, monitor);
			if (this.inDefault) {
				doComputeMainProposals(context, node, proposals, monitor);
			}
			
			if (this.mode == 0 && this.inDefault) {
				doComputeKeywordProposals(context, proposals, monitor);
			}
			
			if (this.mode == 0) {
				if (isPackageName(prefixName)) {
					if (this.pkgNamePrio > 0) {
						doComputePkgNameProposals(context, this.pkgNamePrio, proposals);
					}
					else if (!prefixName.getSegmentName().isEmpty()) {
						doComputePkgNameProposals(context, ARG_TYPE_NO_PRIO, proposals);
					}
				}
				{	if (this.helpTopicPrio > 0) {
						doComputeHelpTopicProposals(context, null, node, this.helpTopicPrio, proposals);
					}
				}
			}
		}
		else {
			doComputeSubProposals(context, node, proposals, monitor);
		}
	}
	
	
	private @Nullable String checkHelp(final RAssistInvocationContext context) {
		try {
			if (context.getIdentifierOffset() > 0
					&& context.getDocument().getChar(context.getIdentifierOffset() - 1) == '?') {
				final String prefix= context.computeIdentifierPrefix(context.getIdentifierOffset() - 1);
				if (prefix != null && !prefix.isEmpty()) {
					if (prefix.equals("class") || prefix.equals("methods")) { //$NON-NLS-1$ //$NON-NLS-2$
						return prefix;
					}
					return null;
				}
				return ""; //$NON-NLS-1$
			}
			return null;
		}
		catch (final BadPartitioningException | BadLocationException e) {
			return null;
		}
	}
	
	protected List<? extends IRLangElement> getChildren(final RAssistInvocationContext context,
			IRLangElement e) {
		if (e instanceof RReference) {
			final RReference ref= (RReference) e;
			final RObject rObject= ref.getResolvedRObject();
			if (rObject == null && e instanceof CombinedRElement && context.getTool() != null) {
				context.getToolReferencesUtil().resolve(ref, 0);
			}
			if (rObject instanceof CombinedRElement) {
				e= (CombinedRElement) rObject;
			}
		}
		return e.getModelChildren(null);
	}
	
	protected boolean doComputeArgumentProposals(final RAssistInvocationContext context,
			final AssistProposalCollector proposals,
			final IProgressMonitor monitor) {
		final FCallInfo fCallInfo= context.getFCallInfo();
		if (fCallInfo != null) {
			boolean argName= false;
			boolean argValue= false;
			final int argIdx= fCallInfo.getArgIdx(context.getInvocationOffset());
			if (argIdx >= 0) {
				final FCall.Arg arg= fCallInfo.getArg(argIdx);
				final int argBeginOffset= fCallInfo.getArgBeginOffset(argIdx);
				
				IDocument document= context.getDocument();
				int offsetShift= 0;
				if (document instanceof IFragmentDocument) {
					final IFragmentDocument inputDoc= (IFragmentDocument) document;
					document= inputDoc.getMasterDocument();
					offsetShift= inputDoc.getOffsetInMasterDocument();
				}
				
				if (argBeginOffset != Integer.MIN_VALUE) {
					final RHeuristicTokenScanner scanner= context.getRHeuristicTokenScanner();
					scanner.configure(document, NO_R_COMMENT_CONSTRAINT);
					final int offset= context.getIdentifierOffset();
					if (argBeginOffset == offset
							|| scanner.findNonBlankForward(
									argBeginOffset + offsetShift, offset + offsetShift, true) < 0 ) {
						argName= (this.inDefault
								&& (context.getIdentifierElementName().getScope() == null) );
						argValue= true;
					}
				}
				
				if (!argValue && arg != null && arg.getAssignOffset() != AstNode.NA_OFFSET) {
					final RHeuristicTokenScanner scanner= context.getRHeuristicTokenScanner();
					scanner.configure(document, NO_R_COMMENT_CONSTRAINT);
					final int offset= context.getIdentifierOffset();
					if (argBeginOffset == offset
							|| scanner.findNonBlankForward(
									arg.getAssignOffset() + offsetShift + 1, offset + offsetShift, true) < 0 ) {
						argValue= true;
					}
				}
			}
			if (argName || argValue) {
				doComputeFCallArgumentProposals(context, fCallInfo, argIdx, argName, argValue,
						proposals);
				return true;
			}
		}
		return false;
	}
	
	protected void doComputeMainProposals(final RAssistInvocationContext context,
			final RAstNode node,
			final AssistProposalCollector proposals,
			final IProgressMonitor monitor) {
		final RElementName prefixName= context.getIdentifierElementName();
		final String prefixSegmentName= nonNullAssert(prefixName.getSegmentName());
		
		this.searchPath.init(context, node, getSearchMode(context), prefixName.getScope());
		
		final RElementProposalParameters parameters= new RElementProposalParameters(
				context, context.getIdentifierLastSegmentOffset(),
				new RSearchPattern(getSearchMatchRules(), prefixSegmentName),
				this.labelProvider );
		
		final Set<String> mainNames= new HashSet<>();
		final List<String> methodNames= new ArrayList<>();
		
		for (final RFrameIterator iter= this.searchPath.iterator(); iter.hasNext();) {
			final IRFrame envir= iter.next();
			parameters.baseRelevance= iter.getRelevance();
			
			final List<? extends IRElement> elements= envir.getModelChildren(null);
			for (final IRElement element : elements) {
				final RElementName elementName= element.getElementName();
				final int c1type= (element.getElementType() & IModelElement.MASK_C1);
				final boolean isRich= (c1type == IModelElement.C1_METHOD);
				if ((isRich || c1type == IModelElement.C1_VARIABLE)
						&& isCompletable(elementName)
						&& parameters.matchesNamePattern(elementName.getSegmentName()) ) {
					if ((parameters.baseRelevance < 0) && !isRich
							&& mainNames.contains(elementName.getSegmentName()) ) {
						continue;
					}
					parameters.replacementName= elementName;
					parameters.element= element;
					
					final AssistProposal proposal= new RElementCompletionProposal(parameters);
					if (elementName.getNextSegment() == null) {
						if (isRich) {
							methodNames.add(elementName.getSegmentName());
						}
						else {
							mainNames.add(elementName.getSegmentName());
						}
					}
					proposals.add(proposal);
				}
			}
		}
		
		mainNames.addAll(methodNames);
		for (final RFrameIterator iter= this.searchPath.iterator(); iter.hasNext();) {
			final IRFrame envir= iter.next();
			parameters.baseRelevance= 0;
			
			if (envir instanceof IRFrameInSource) {
				final IRFrameInSource sframe= (IRFrameInSource) envir;
				final Set<String> elementNames= sframe.getAllAccessNames();
				for (final String candidate : elementNames) {
					if (candidate != null
							&& !(candidate.equals(prefixSegmentName)
									&& (sframe.getAllAccessOf(candidate, false).size() <= 1) )
							&& !mainNames.contains(candidate)
							&& parameters.matchesNamePattern(candidate) ) {
						
						final AssistProposal proposal= new RSimpleCompletionProposal(parameters,
								candidate );
						mainNames.add(candidate);
						proposals.add(proposal);
					}
				}
			}
		}
	}
	
	private void doComputeKeywordProposals(final RAssistInvocationContext context,
			final AssistProposalCollector proposals,
			final IProgressMonitor monitor) {
		final RElementName prefixName= context.getIdentifierElementName();
		final String prefixSegmentName= nonNullAssert(prefixName.getSegmentName());
		
		if (prefixName.getScope() != null) {
			return;
		}
		
		final String prefixSource= context.getIdentifierPrefix();
		if (!prefixSegmentName.isEmpty() && prefixSource.charAt(0) != '`') {
			final ProposalParameters<RAssistInvocationContext> parameters= new ProposalParameters<>(
					context, context.getIdentifierOffset(),
					new RSearchPattern(SearchPattern.PREFIX_MATCH, prefixSegmentName) );
			
			final List<String> keywords= fgKeywords;
			for (final String keyword : keywords) {
				if (parameters.matchesNamePattern(keyword)) {
					proposals.add(new RSimpleCompletionProposal(parameters, keyword));
				}
			}
		}
	}
	
	protected void doComputeSubProposals(final RAssistInvocationContext context,
			final RAstNode node,
			final AssistProposalCollector proposals,
			final IProgressMonitor monitor) {
		final RElementName prefixName= context.getIdentifierElementName();
		
		this.searchPath.init(context, node, getSearchMode(context), prefixName.getScope());
		
		int count= 0;
		final String namePrefix;
		{	RElementName prefixSegment= prefixName;
			while (true) {
				count++;
				if (prefixSegment.getNextSegment() != null) {
					prefixSegment= prefixSegment.getNextSegment();
					continue;
				}
				else {
					break;
				}
			}
			namePrefix= (prefixSegment.getSegmentName() != null) ?
					prefixSegment.getSegmentName() : ""; //$NON-NLS-1$
		}
		
		final RElementProposalParameters parameters= new RElementProposalParameters(
				context, context.getIdentifierLastSegmentOffset(),
				new RSearchPattern(getSearchMatchRules(), namePrefix),
				this.labelProvider );
		
		final Set<String> mainNames= new HashSet<>();
		final List<String> methodNames= new ArrayList<>();
		
		for (final RFrameIterator iter= this.searchPath.iterator(); iter.hasNext();) {
			final IRFrame envir= iter.next();
			parameters.baseRelevance= iter.getRelevance();
			
			final List<? extends IRLangElement> elements= envir.getModelChildren(null);
			ITER_ELEMENTS: for (final IRLangElement rootElement : elements) {
				final RElementName elementName= rootElement.getElementName();
				final int c1type= (rootElement.getElementType() & IModelElement.MASK_C1);
				final boolean isRich= (c1type == IModelElement.C1_METHOD);
				if (isRich || c1type == IModelElement.C1_VARIABLE) {
					IRLangElement element= rootElement;
					RElementName prefixSegment= prefixName;
					RElementName elementSegment= elementName;
					ITER_SEGMENTS: for (int i= 0; i < count-1; i++) {
						if (elementSegment == null) {
							final List<? extends IRLangElement> children= getChildren(context, element);
							for (final IRLangElement child : children) {
								elementSegment= child.getElementName();
								if (isCompletable(elementSegment)
										&& elementSegment.getSegmentName().equals(prefixSegment.getSegmentName())) {
									element= child;
									prefixSegment= prefixSegment.getNextSegment();
									elementSegment= elementSegment.getNextSegment();
									continue ITER_SEGMENTS;
								}
							}
							continue ITER_ELEMENTS;
						}
						else {
							if (isCompletable(elementSegment)
									&& elementSegment.getSegmentName().equals(prefixSegment.getSegmentName())) {
								prefixSegment= prefixSegment.getNextSegment();
								elementSegment= elementSegment.getNextSegment();
								continue ITER_SEGMENTS;
							}
							continue ITER_ELEMENTS;
						}
					}
					
					final boolean childMode;
					final List<? extends IRLangElement> children;
					if (elementSegment == null) {
						childMode= true;
						children= getChildren(context, element);
					}
					else {
						childMode= false;
						children= Collections.singletonList(element);
					}
					for (final IRLangElement child : children) {
						if (childMode) {
							elementSegment= child.getElementName();
						}
						final String candidate= elementSegment.getSegmentName();
						if (isCompletable(elementSegment)
								&& parameters.matchesNamePattern(candidate) ) {
							if ((parameters.baseRelevance > 0) && !isRich
									&& mainNames.contains(candidate) ) {
								continue ITER_ELEMENTS;
							}
							parameters.replacementName= elementSegment;
							parameters.element= child;
							
							final AssistProposal proposal= new RElementCompletionProposal(parameters);
							if (elementSegment.getNextSegment() == null) {
								if (isRich) {
									methodNames.add(candidate);
								}
								else {
									mainNames.add(candidate);
								}
							}
							proposals.add(proposal);
						}
					}
				}
			}
		}
		
		mainNames.addAll(methodNames);
		for (final RFrameIterator iter= this.searchPath.iterator(); iter.hasNext();) {
			final IRFrame envir= iter.next();
			parameters.baseRelevance= 0;
			
			if (envir instanceof IRFrameInSource) {
				final IRFrameInSource sframe= (IRFrameInSource) envir;
				final List<? extends RElementAccess> allAccess= sframe.getAllAccessOf(
						prefixName.getSegmentName(), true );
				if (allAccess != null) {
					ITER_ELEMENTS: for (final RElementAccess elementAccess : allAccess) {
						RElementAccess elementSegment= elementAccess;
						RElementName prefixSegment= prefixName;
						ITER_SEGMENTS: for (int i= 0; i < count - 1; i++) {
							if (isCompletable(elementSegment)
									&& elementSegment.getSegmentName().equals(prefixSegment.getSegmentName())) {
								prefixSegment= prefixSegment.getNextSegment();
								elementSegment= elementSegment.getNextSegment();
								continue ITER_SEGMENTS;
							}
							continue ITER_ELEMENTS;
						}
						
						if (elementSegment == null || elementSegment.isSlave()) {
							continue ITER_ELEMENTS;
						}
						final String candidate= elementSegment.getSegmentName();
						if (candidate != null && isCompletable(elementSegment)
								&& !candidate.equals(namePrefix)
								&& !mainNames.contains(candidate)
								&& parameters.matchesNamePattern(candidate) ) {
							
							final AssistProposal proposal= new RSimpleCompletionProposal(parameters,
									candidate );
							mainNames.add(candidate);
							proposals.add(proposal);
						}
					}
				}
			}
		}
	}
	
	public void doComputeContextProposals(final RAssistInvocationContext context,
			final AssistProposalCollector proposals, final IProgressMonitor monitor) {
		if (context.getModelInfo() == null) {
			return;
		}
		
		final RAssistInvocationContext.FCallInfo fCallInfo= context.getFCallInfo();
		if (fCallInfo != null) {
			final RElementProposalParameters parameters= new RElementProposalParameters(
					context, Math.max(fCallInfo.getNode().getArgsOpenOffset() + 1, 0),
					this.labelProvider );
			
			final FCallNamePattern pattern= new FCallNamePattern(fCallInfo.getAccess()) {
				@Override
				protected void handleMatch(final IRMethod element, final IRFrame frame,
						final RFrameIterator iterator) {
					parameters.baseRelevance= iterator.getRelevance();
					parameters.replacementName= element.getElementName();
					parameters.element= element;
					
					proposals.add(new RElementCompletionProposal.ContextInformationProposal(parameters));
				}
			};
			pattern.searchFDef(fCallInfo.getSearchPath(getSearchMode(context)));
		}
	}
	
	
	protected final boolean isPackageArg(final String name) {
		return ("package".equals(name));
	}
	
	private void doComputeFCallArgumentProposals(final RAssistInvocationContext context,
			final FCallInfo fCallInfo, final int argIdx, final boolean argName, final boolean argValue,
			final AssistProposalCollector proposals) {
		final RElementName prefixName= context.getIdentifierElementName();
		final String prefixSegmentName= nonNullAssert(prefixName.getSegmentName());
		
		if (argValue && !argName) {
			final FCall.Arg arg= fCallInfo.getArg(argIdx);
			if (arg != null && arg.hasName()) {
				if (this.inString && isPackageArg(arg.getNameChild().getText())) {
					this.pkgNamePrio= ARG_TYPE_PRIO;
				}
			}
		}
		
		final RElementProposalParameters parameters= new RElementProposalParameters(
				context, context.getIdentifierOffset(),
				new RSearchPattern(getSearchMatchRules(), prefixSegmentName),
				this.labelProvider );
		
		class FCallHandler extends FCallNamePattern {
			
			private final @Nullable RCoreFunctions coreFunction;
			
			private final HashSet<String> argNames= new HashSet<>();
			
			private int matchCount;
			
			
			FCallHandler() {
				super(fCallInfo.getAccess());
				
				if (fCallInfo.getAccess().getNextSegment() == null) {
					this.coreFunction= RCoreFunctions.DEFAULT;
				}
				else {
					this.coreFunction= null;
				}
			}
			
			
			private boolean isValidNameContext(final ArgsDefinition.Arg argDef) {
				if (RElementCompletionComputer.this.inString) {
					return ((argDef.type & ArgsDefinition.NAME_AS_STRING) != 0);
				}
				else {
					return ((argDef.type & ArgsDefinition.NAME_AS_SYMBOL) != 0);
				}
			}
			
			private boolean checkArgsDef(final FCallArgMatch args,
					final boolean guess, final int relevance) {
				final ArgsDefinition.Arg argDef= args.getArgDef(argIdx);
				if (argDef != null) {
					final boolean typedDef= (argDef.type != 0);
					if (RElementCompletionComputer.this.pkgNamePrio == NA_PRIO) {
						if (typedDef) {
							if ((argDef.type & ArgsDefinition.PACKAGE_NAME) != 0
									&& isValidNameContext(argDef) ) {
								RElementCompletionComputer.this.pkgNamePrio= ARG_TYPE_PRIO + relevance;
							}
						}
						else if (guess && RElementCompletionComputer.this.inString && isPackageArg(argDef.name)) {
							RElementCompletionComputer.this.pkgNamePrio= ARG_TYPE_PRIO + relevance;
						}
					}
					if (RElementCompletionComputer.this.helpTopicPrio == NA_PRIO) {
						if (typedDef) {
							if ((argDef.type & ArgsDefinition.HELP_TOPIC_NAME) != 0
									&& isValidNameContext(argDef) ) {
								RElementCompletionComputer.this.helpTopicPrio= ARG_TYPE_PRIO + relevance;
							}
						}
					}
					return typedDef;
				}
				return false;
			}
			
			@Override
			public void searchFDef(final RFrameSearchPath searchPath) {
				super.searchFDef(searchPath);
				
				if (this.matchCount == 0
						&& this.coreFunction != null) {
					final FCall.Args callArgs= fCallInfo.getNode().getArgsChild();
					
					final ArgsDefinition coreDef= this.coreFunction.getArgs(
							getElementName().getSegmentName() );
					if (coreDef != null) {
						checkArgsDef(RAst.matchArgs(callArgs, coreDef), false, 0);
					}
				}
			}
			
			@Override
			protected void handleMatch(final IRMethod element, final IRFrame frame,
					final RFrameIterator iter) {
				final ArgsDefinition argsDef= element.getArgsDefinition();
				if (argsDef == null) {
					return;
				}
				
				final int contextRelevance= iter.getRelevance();
				this.matchCount++;
				
				if (argName) {
					for (int i= 0; i < argsDef.size(); i++) {
						final ArgsDefinition.Arg arg= argsDef.get(i);
						if (arg.name != null && arg.name.length() > 0 && !arg.name.equals("...")) {
							if (parameters.matchesNamePattern(arg.name)
									&& this.argNames.add(arg.name)) {
								final RElementName name= RElementName.create(RElementName.MAIN_DEFAULT, arg.name);
								parameters.baseRelevance= contextRelevance + ARG_NAME_PRIO;
								parameters.replacementName= name;
								parameters.element= element;
								
								proposals.add(new RElementCompletionProposal.ArgumentProposal(parameters));
							}
						}
					}
				}
				if (argValue) {
					final FCall.Args callArgs= fCallInfo.getNode().getArgsChild();
					if (!checkArgsDef(RAst.matchArgs(callArgs, argsDef), true, contextRelevance)
							&& frame.getFrameType() == IRFrame.PACKAGE
							&& this.coreFunction != null
							&& this.coreFunction.getPackageNames().contains(frame.getElementName().getSegmentName()) ) {
						final ArgsDefinition coreDef= this.coreFunction.getArgs(
								getElementName().getSegmentName() );
						if (coreDef != null) {
							checkArgsDef(RAst.matchArgs(callArgs, coreDef), false, contextRelevance);
						}
					}
				}
			}
			
		}
		final FCallHandler search= new FCallHandler();
		search.searchFDef(fCallInfo.getSearchPath(getSearchMode(context)));
	}
	
	
	protected final @Nullable RPkgManagerDataset getRPkgDataset(final RAssistInvocationContext context) {
		final IRPkgManager manager= RCore.getRPkgManager(context.getRCoreAccess().getREnv());
		if (manager != null) {
			return manager.getDataset();
		}
		return null;
	}
	
	protected final boolean isPackageName(final RElementName elementName) {
		return ((elementName.getType() == RElementName.MAIN_DEFAULT 
						|| RElementName.isPackageFacetScopeType(elementName.getType()) )
				&& elementName.getNextSegment() == null );
	}
	
	protected final void doComputePkgNameProposals(final RAssistInvocationContext context,
			final int prio, final AssistProposalCollector proposals) {
		final RElementName prefixName= context.getIdentifierElementName();
		final String prefixSegmentName= nonNullAssert(prefixName.getSegmentName());
		
		if (prefixName.getScope() != null
				|| !isSymbolCandidate(prefixSegmentName)) {
			return;
		}
		
		final RElementProposalParameters parameters= new RElementProposalParameters(
				context, context.getInvocationOffset() - prefixSegmentName.length(),
				new RSearchPattern(getSearchMatchRules(), prefixSegmentName), prio,
				this.labelProvider );
		
		final RPkgManagerDataset rPkgDataset= getRPkgDataset(context);
		
		final Collection<String> envNames;
		if (rPkgDataset != null) {
			final RPkgCompilation<? extends RPkgBuilt> pkgs= rPkgDataset.getInstalled();
			envNames= pkgs.getNames();
			for (final String pkgName : envNames) {
				if (parameters.matchesNamePattern(pkgName)) {
					parameters.replacementName= RElementName.create(RElementName.SCOPE_PACKAGE, pkgName);
					
					final AssistProposal proposal= new RPkgCompletionProposal(parameters,
							pkgs.getFirst(pkgName) );
					proposals.add(proposal);
				}
			}
		}
		else {
			envNames= ImCollections.emptySet();
		}
		
		final Set<String> workspaceNames= RModel.getRModelManager().getPkgNames();
		for (final String pkgName : workspaceNames) {
			if (!envNames.contains(pkgName)
					&& parameters.matchesNamePattern(pkgName) ) {
				parameters.replacementName= RElementName.create(RElementName.SCOPE_PACKAGE, pkgName);
				
				proposals.add(new RPkgCompletionProposal(parameters, null));
			}
		}
	}
	
	protected final void doComputeHelpTopicProposals(final RAssistInvocationContext context,
			final @Nullable String topicType, final RAstNode node,
			final int prio, final AssistProposalCollector proposals) {
		// (topic != null) => ?  /  (topic == null) => help()
		final RElementName prefixName= context.getIdentifierElementName();
		final String prefixSegmentName= nonNullAssert(prefixName.getSegmentName());
		
		if (topicType == null && (prefixName.getScope() != null || prefixSegmentName.isEmpty())) {
			return;
		}
		
		final REnv rEnv= context.getRCoreAccess().getREnv();
		if (rEnv == null) {
			return;
		}
		
		final RHelpManager rHelpManager= RCore.getRHelpManager();
		
		final REnvHelp help= rHelpManager.getHelp(rEnv);
		if (help != null) {
			try {
				final ProposalParameters<RAssistInvocationContext> parameters= new ProposalParameters<>(
						context, (context.getInvocationContentType() != IRDocumentConstants.R_DEFAULT_CONTENT_TYPE) ?
								context.getIdentifierLastSegmentOffset() + 1 :
								context.getIdentifierLastSegmentOffset(),
						new RSearchPattern(getSearchMatchRules(), prefixSegmentName),
						prio );
				final Map<String, RHelpTopicCompletionProposal> map= new HashMap<>();
				this.searchPath.init(context, node, getSearchMode(context), prefixName.getScope());
				final Set<String> pkgNames= new HashSet<>();
				for (final IRFrame frame : this.searchPath) {
					if (frame.getFrameType() == IRFrame.PACKAGE) {
						final String pkgName= frame.getElementName().getSegmentName();
						if (pkgName != null && pkgNames.add(pkgName)) {
							final RPkgHelp pkgHelp= help.getPkgHelp(pkgName);
							if (pkgHelp != null) {
								for (final RHelpTopicEntry topicEntry : pkgHelp.getTopics()) {
									final String topic= topicEntry.getTopic();
									if (parameters.matchesNamePattern(topic)) {
										
										RHelpTopicCompletionProposal proposal= map.get(topic);
										if (proposal == null) {
											proposal= new RHelpTopicCompletionProposal(
													parameters, topic, pkgName );
											map.put(topic, proposal);
											proposals.add(proposal);
										}
										else {
											proposal.addPackage(pkgName);
										}
									}
								}
							}
						}
					}
				}
			}
			finally {
				help.unlock();
			}
		}
	}
	
}
