/*=============================================================================#
 # 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.ecommons.text.ITokenScanner.NOT_FOUND;

import java.util.List;

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

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.TextRegion;
import org.eclipse.statet.jcommons.text.core.input.StringParserInput;
import org.eclipse.statet.jcommons.ts.core.Tool;

import org.eclipse.statet.ecommons.text.core.FragmentDocument;

import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.ast.core.util.AstSelection;
import org.eclipse.statet.ltk.model.core.IModelManager;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.sourceediting.assist.AssistInvocationContext;
import org.eclipse.statet.nico.ui.NicoUITools;
import org.eclipse.statet.nico.ui.console.ConsolePageEditor;
import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.r.console.core.util.LoadReferencesUtil;
import org.eclipse.statet.r.core.IRCoreAccess;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.IRSourceUnit;
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.rlang.RTokens;
import org.eclipse.statet.r.core.rsource.RLexer;
import org.eclipse.statet.r.core.rsource.ast.FCall;
import org.eclipse.statet.r.core.rsource.ast.NodeType;
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.editors.IRSourceEditor;


/**
 * AssistInvocationContext for R
 */
@NonNullByDefault
public class RAssistInvocationContext extends AssistInvocationContext {
	
	
	public class FCallInfo {
		
		private final FCall node;
		
		private final RElementAccess access;
		
		private final int invocationArgIdx;
		
		private @Nullable RFrameSearchPath searchPath;
		
		
		public FCallInfo(final FCall node, final RElementAccess access) {
			this.node= node;
			this.access= access;
			this.invocationArgIdx= getArgIdx(getInvocationOffset());
		}
		
		
		/**
		 * Returns the node of the function call.
		 * @return the ast node
		 */
		public FCall getNode() {
			return this.node;
		}
		
		/**
		 * Returns the element access of the function belonging to the function call.
		 * @return the element access
		 */
		public RElementAccess getAccess() {
			return this.access;
		}
		
		private RFrameSearchPath createSearchPath(final int mode) {
			final RFrameSearchPath searchPath= new RFrameSearchPath();
			final RAstNode parent= this.node.getRParent();
			searchPath.init(RAssistInvocationContext.this, (parent != null) ? parent : this.node,
					mode, getAccess().getScope() );
			return searchPath;
		}
		
		public RFrameSearchPath getSearchPath(final int mode) {
			final int defaultMode= getDefaultRFrameSearchMode();
			if (mode == 0 || mode == defaultMode) {
				@Nullable RFrameSearchPath searchPath= this.searchPath;
				if (searchPath == null) {
					searchPath= createSearchPath(defaultMode);
					this.searchPath= searchPath;
				}
				return searchPath;
			}
			else {
				return createSearchPath(mode);
			}
		}
		
		public int getArgIdx(final int offset) {
			if (offset <= this.node.getArgsOpenOffset()
					|| (this.node.getArgsCloseOffset() != Integer.MIN_VALUE 
							&& offset > this.node.getArgsCloseOffset() )) {
				return -1;
			}
			final FCall.Args args= this.node.getArgsChild();
			final int last= args.getChildCount() - 1;
			if (last < 0) {
				return 0;
			}
			for (int argIdx= 0; argIdx < last; argIdx++) {
				if (args.getSeparatorOffset(argIdx) >= offset) {
					return argIdx;
				}
			}
			return last;
		}
		
		public int getArgBeginOffset(final int argIdx) {
			if (argIdx < 0) {
				return AstNode.NA_OFFSET;
			}
			final int sep= (argIdx == 0) ?
					this.node.getArgsOpenOffset() :
					this.node.getArgsChild().getSeparatorOffset(argIdx - 1);
			return sep + 1;
		}
		
		public FCall. @Nullable Arg getArg(final int argIdx) {
			if (argIdx < 0) {
				return null;
			}
			final FCall.Args args= this.node.getArgsChild();
			return (argIdx < args.getChildCount()) ? args.getChild(argIdx) : null;
		}
		
		/**
		 * Returns the index of the argument at the {@link RAssistInvocationContext#getInvocationOffset() invocation offset}.
		 * @return the index of the argument
		 */
		public final int getInvocationArgIdx() {
			return this.invocationArgIdx;
		}
		
	}
	
	
	private static final byte PARSE_OPERATOR=               1 << 0;
	private static final byte PARSE_SYMBOL=                 1 << 1;
	
	
	private @Nullable RHeuristicTokenScanner scanner;
	private @Nullable RLexer lexer;
	
	private @Nullable RElementName prefixName;
	
	private int prefixLastSegmentOffset= -1;
	
	
	private final @Nullable RProcess tool;
	
	private @Nullable LoadReferencesUtil toolReferencesUtil;
	
	
	public RAssistInvocationContext(final IRSourceEditor editor,
			final int offset, final String contentType,
			final boolean isProposal,
			final RHeuristicTokenScanner scanner,
			final IProgressMonitor monitor) {
		super(editor, offset, contentType,
				(isProposal) ? IModelManager.MODEL_FILE : IModelManager.NONE, monitor );
		
		this.scanner= scanner;
		
		this.tool= determineRProcess();
	}
	
	public RAssistInvocationContext(final IRSourceEditor editor,
			final IRegion region, final String contentType,
			final RHeuristicTokenScanner scanner,
			final IProgressMonitor monitor) {
		super(editor, region, contentType, IModelManager.MODEL_FILE, monitor);
		
		this.scanner= scanner;
		
		this.tool= determineRProcess();
	}
	
	
	private @Nullable RProcess determineRProcess() {
		final ISourceEditor editor= getEditor();
		final Tool tool;
		if (editor instanceof ConsolePageEditor) {
			tool= editor.getAdapter(Tool.class);
		}
		else {
			tool= NicoUITools.getTool(editor.getWorkbenchPart());
		}
		return (tool instanceof RProcess) ? (RProcess) tool : null;
	}
	
	
	@Override
	protected boolean reuse(final ISourceEditor editor, final int offset) {
		if (super.reuse(editor, offset)) {
			final LoadReferencesUtil toolReferencesUtil= this.toolReferencesUtil;
			if (toolReferencesUtil != null) {
				toolReferencesUtil.setWaitTimeout(getToolReferencesWaitTimeout());
			}
			return true;
		}
		return false;
	}
	
	
	@Override
	protected String getModelTypeId() {
		return RModel.R_TYPE_ID;
	}
	
	@Override
	public IRSourceEditor getEditor() {
		return (IRSourceEditor) super.getEditor();
	}
	
	@Override
	public @Nullable IRSourceUnit getSourceUnit() {
		return (IRSourceUnit) super.getSourceUnit();
	}
	
	public IRCoreAccess getRCoreAccess() {
		return getEditor().getRCoreAccess();
	}
	
	
	public final RHeuristicTokenScanner getRHeuristicTokenScanner() {
		RHeuristicTokenScanner scanner= this.scanner;
		if (scanner == null) {
			scanner= RHeuristicTokenScanner.create(getEditor().getDocumentContentInfo());
			this.scanner= scanner;
		}
		return scanner;
	}
	
	protected RLexer getLexer() {
		RLexer lexer= this.lexer;
		if (lexer == null) {
			lexer= new RLexer((RLexer.DEFAULT |
					RLexer.SKIP_WHITESPACE | RLexer.SKIP_LINEBREAK | RLexer.SKIP_COMMENT ));
			lexer.reset(new StringParserInput());
			this.lexer= lexer;
		}
		return lexer;
	}
	
	
	@Override
	protected String computeIdentifierPrefix(final int endOffset)
			throws BadPartitioningException, BadLocationException {
		final AbstractDocument document= (AbstractDocument) getDocument();
		
		if (endOffset < 0 || endOffset > document.getLength()) {
			throw new BadLocationException("offset= " + endOffset); //$NON-NLS-1$
		}
		if (endOffset == 0) {
			return ""; //$NON-NLS-1$
		}
		
		int offset= endOffset;
		byte currentMode= (PARSE_SYMBOL | PARSE_OPERATOR);
		byte validModes= (PARSE_SYMBOL | PARSE_OPERATOR);
		final String partitioning= getEditor().getDocumentContentInfo().getPartitioning();
		ITypedRegion partition= document.getPartition(partitioning, offset, true);
		if (partition.getType() == IRDocumentConstants.R_QUOTED_SYMBOL_CONTENT_TYPE
				|| partition.getType() == IRDocumentConstants.R_STRING_CONTENT_TYPE) {
			offset= partition.getOffset();
			currentMode= PARSE_OPERATOR;
		}
		int startOffset= offset;
		SEARCH_START: while (offset > 0) {
			final char c= document.getChar(offset - 1);
			if (RTokens.isRobustSeparator(c)) {
				switch (c) {
				case '$':
				case '@':
					if ((currentMode & PARSE_OPERATOR) != 0) {
						offset--;
						startOffset= offset;
						currentMode= (byte) (validModes & PARSE_SYMBOL);
						continue SEARCH_START;
					}
					break SEARCH_START;
				case ':':
					if ((currentMode & PARSE_OPERATOR) != 0
							&& offset >= 2 && document.getChar(offset - 2) == ':') {
						if (offset >= 3 && document.getChar(offset - 3) == ':') {
							offset-= 3;
						}
						else {
							offset-= 2;
						}
						validModes&= ~PARSE_OPERATOR;
						currentMode= (byte) (validModes & PARSE_SYMBOL);
						continue SEARCH_START;
					}
					break SEARCH_START;
//					case ' ':
//					case '\t':
//						if (offset >= 2) {
//							final char c2= document.getChar(offset - 2);
//							if ((offset == getInvocationOffset()) ? 
//									!RTokens.isRobustSeparator(c2, false) :
//									(c2 == '$' && c2 == '@')) {
//								offset-= 2;
//								continue SEARCH_START;
//							}
//						}
//						break SEARCH_START;
				case '`':
					if ((currentMode & PARSE_SYMBOL) != 0) {
						partition= document.getPartition(partitioning, offset - 1, false);
						if (partition.getType() == IRDocumentConstants.R_QUOTED_SYMBOL_CONTENT_TYPE) {
							offset= partition.getOffset();
							startOffset= offset;
							currentMode= (byte) (validModes & PARSE_OPERATOR);
							continue SEARCH_START;
						}
					}
					break SEARCH_START;
				
				default:
					break SEARCH_START;
				}
			}
			else {
				if ((currentMode & PARSE_SYMBOL) != 0) {
					offset--;
					startOffset= offset;
					currentMode|= (byte) (validModes & PARSE_OPERATOR);
					continue SEARCH_START;
				}
				break SEARCH_START;
			}
		}
		
		return document.get(startOffset, endOffset - startOffset);
	}
	
	protected int computeIdentifierPrefixLastSegmentOffset(final int endOffset)
			throws BadPartitioningException, BadLocationException {
		final AbstractDocument document= (AbstractDocument) getDocument();
		
		if (endOffset < 0 || endOffset > document.getLength()) {
			throw new BadLocationException("endOffset= " + endOffset); //$NON-NLS-1$
		}
		if (endOffset == 0) {
			return 0;
		}
		
		int offset= endOffset;
		final String partitioning= getEditor().getDocumentContentInfo().getPartitioning();
		final ITypedRegion partition= document.getPartition(partitioning, offset, true);
		if (partition.getType() == IRDocumentConstants.R_QUOTED_SYMBOL_CONTENT_TYPE
				|| partition.getType() == IRDocumentConstants.R_STRING_CONTENT_TYPE) {
			return partition.getOffset();
		}
		int startOffset= offset;
		SEARCH_START: while (offset > 0) {
			final char c= document.getChar(offset - 1);
			if (RTokens.isRobustSeparator(c, false)) {
				break SEARCH_START;
			}
			else {
				offset--;
				startOffset= offset;
			}
		}
		
		return startOffset;
	}
	
	public @Nullable RElementName getIdentifierElementName() {
		if (this.prefixName == null) {
			this.prefixName= RElementName.parseDefault(getIdentifierPrefix());
		}
		return this.prefixName;
	}
	
	public int getIdentifierLastSegmentOffset() {
		if (this.prefixLastSegmentOffset < 0) {
			try {
				this.prefixLastSegmentOffset= computeIdentifierPrefixLastSegmentOffset(
						getInvocationOffset() );
			}
			catch (final BadPartitioningException | BadLocationException e) {
				this.prefixLastSegmentOffset= getInvocationOffset();
				throw new RuntimeException(e);
			}
		}
		return this.prefixLastSegmentOffset;
	}
	
	
	public @Nullable String getIdentifierSegmentName(final String source) {
		final RLexer lexer= getLexer();
		((StringParserInput) lexer.getInput()).reset(source).init();
		lexer.reset();
		
		switch (lexer.next()) {
		case EOF:
			return "";
		default:
			return lexer.getText();
		}
	}
	
	private static @Nullable RElementName getElementAccessOfRegion(final RElementAccess access,
			final TextRegion region) {
		RElementAccess current= access;
		while (current != null) {
			if (current.getSegmentName() == null) {
				return null;
			}
			switch (current.getType()) {
			case RElementName.SCOPE_NS:
			case RElementName.SCOPE_NS_INT:
			case RElementName.SCOPE_SEARCH_ENV:
			case RElementName.SCOPE_PACKAGE:
			
			case RElementName.MAIN_DEFAULT:
			case RElementName.MAIN_CLASS:
			
			case RElementName.SUB_NAMEDSLOT:
			case RElementName.SUB_NAMEDPART:
				break;
			default:
				return null;
			}
			
			final RAstNode nameNode= current.getNameNode();
			if (nameNode != null
					&& nameNode.getStartOffset() <= region.getStartOffset()
					&& nameNode.getEndOffset() >= region.getEndOffset() ) {
				return RElementName.create(access, current.getNextSegment(), true);
			}
			current= current.getNextSegment();
		}
		
		return null;
	}
	
	public @Nullable RElementName getNameSelection() {
		final AstNode selectedNode= getAstSelection().getCovering();
		if (selectedNode instanceof RAstNode) {
			RAstNode node= (RAstNode) selectedNode;
			RElementAccess access= null;
			while (node != null && access == null) {
				if (Thread.interrupted()) {
					return null;
				}
				final List<Object> attachments= node.getAttachments();
				for (final Object attachment : attachments) {
					if (attachment instanceof RElementAccess) {
						node= null;
						access= (RElementAccess) attachment;
						final RElementName e= getElementAccessOfRegion(access, this);
						if (e != null) {
							return e;
						}
						if (Thread.interrupted()) {
							return null;
						}
					}
				}
				if (node != null) {
					node= node.getRParent();
				}
			}
		}
		return null;
	}
	
	
	public @Nullable FCallInfo getFCallInfo() {
		// This should be equals or more strict than the validation by RContextInformationValidator
		// (RScanner.scanFCallArgs(..., expand= true))
		
		// Unclosed function calls ends at last valid char, which is too strict for assists.
		// Try to expand the argument list to also include whitespaces behind the last valid char /
		// go back to last valid char.
		final int endOffset= findRelevantOffsetBackward(getEndOffset());
		final int startOffset= Math.min(getStartOffset(), endOffset);
		
		final FCall fCallNode= searchFCallByArgsRegion(startOffset, endOffset);
		if (fCallNode != null) {
			final List<Object> attachments= fCallNode.getAttachments();
			for (final Object attachment : attachments) {
				if (attachment instanceof RElementAccess) {
					final RElementAccess fcallAccess= (RElementAccess)attachment;
					if (fcallAccess.getNode() == fCallNode
							&& fcallAccess.isFunctionAccess() && !fcallAccess.isWriteAccess()) {
						return new FCallInfo(fCallNode, fcallAccess);
					}
				}
			}
		}
		return null;
	}
	
	private int findRelevantOffsetBackward(final int offset) {
		int docOffset= offset;
		int docOffsetShift= 0;
		IDocument document= getDocument();
		if (document instanceof FragmentDocument) {
			final FragmentDocument fragmentDoc= (FragmentDocument)document;
			document= fragmentDoc.getMasterDocument();
			docOffsetShift= fragmentDoc.getOffsetInMasterDocument();
			docOffset+= docOffsetShift;
		}
		if (docOffset > 0) {
			try {
				final RHeuristicTokenScanner scanner= getRHeuristicTokenScanner();
				final int bound= document.getLineOffset(
						Math.max(document.getLineOfOffset(docOffset) - 2, 0) );
				
				scanner.configure(document, IRDocumentConstants.R_NO_COMMENT_CONTENT_CONSTRAINT);
				docOffset= scanner.findNonBlankBackward(docOffset, bound - 1, true);
				if (docOffset != NOT_FOUND) {
					return docOffset + 1 - docOffsetShift; // behind first relevant
				}
			}
			catch (final BadLocationException e) {}
		}
		return offset;
	}
	
	private @Nullable FCall searchFCallByArgsRegion(final int startOffset, final int endOffset) {
		final AstInfo astInfo= getAstInfo();
		if (astInfo == null || astInfo.getRoot() == null) {
			return null;
		}
		final AstSelection selection= AstSelection.search(astInfo.getRoot(),
				startOffset, endOffset, AstSelection.MODE_COVERING_SAME_LAST );
		final AstNode node= selection.getCovering();
		
		if (node instanceof RAstNode) {
			RAstNode rNode= (RAstNode)node;
			do {
				if (rNode.getNodeType() == NodeType.F_CALL) {
					final FCall fCallNode= (FCall)rNode;
					if (fCallNode.getArgsOpenOffset() != AstNode.NA_OFFSET
							&& fCallNode.getArgsOpenOffset() < startOffset
							&& (fCallNode.getArgsCloseOffset() == AstNode.NA_OFFSET
									|| fCallNode.getArgsCloseOffset() >= endOffset )) {
						return fCallNode;
					}
				}
				rNode= rNode.getRParent();
			} while (rNode != null);
		}
		
		return null;
	}
	
	
	public @Nullable RProcess getTool() {
		return this.tool;
	}
	
	public boolean isToolConsole() {
		return (getEditor() instanceof ConsolePageEditor);
	}
	
	public LoadReferencesUtil getToolReferencesUtil() {
		assert (this.tool != null);
		
		LoadReferencesUtil util= this.toolReferencesUtil;
		if (util == null) {
			util= new LoadReferencesUtil(this.tool, getToolReferencesWaitTimeout()) {
				@Override
				protected void allFinished(final ImList<CombinedRElement> resolvedElements) {
					if (!resolvedElements.isEmpty()) {
						RAssistInvocationContext.this.toolReferencesResolved(resolvedElements);
					}
				}
			};
			this.toolReferencesUtil= util;
		}
		return util;
	}
	
	protected int getToolReferencesWaitTimeout() {
		return LoadReferencesUtil.MAX_EXPLICITE_WAIT;
	}
	
	protected void toolReferencesResolved(final ImList<CombinedRElement> resolvedElements) {
	}
	
	
	public int getDefaultRFrameSearchMode() {
		return (isToolConsole()) ? RFrameSearchPath.CONSOLE_MODE : RFrameSearchPath.WORKSPACE_MODE;
	}
	
}
