/*=============================================================================#
 # 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.FragmentDocument;
import org.eclipse.statet.ecommons.text.core.PartitionConstraint;

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 PartitionConstraint NO_R_COMMENT_CONSTRAINT= new PartitionConstraint() {
		@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.getInvocationArgIdx();
			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 FragmentDocument) {
					final FragmentDocument inputDoc= (FragmentDocument) 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, fCallInfo.getNode().getArgsOpenOffset() + 1,
					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();
			}
		}
	}
	
}
