/*=============================================================================#
 # 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.core.refactoring;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.osgi.util.NLS;
import org.eclipse.text.edits.TextEdit;

import org.eclipse.statet.jcommons.text.core.BasicTextRegion;
import org.eclipse.statet.jcommons.text.core.TextRegion;
import org.eclipse.statet.jcommons.text.core.input.StringParserInput;
import org.eclipse.statet.jcommons.text.core.input.TextParserInput;

import org.eclipse.statet.ecommons.text.IndentUtil;
import org.eclipse.statet.ecommons.text.core.IPartitionConstraint;

import org.eclipse.statet.internal.r.core.refactoring.Messages;
import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.ltk.ast.core.util.AstSelection;
import org.eclipse.statet.ltk.model.core.IModelManager;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnitModelInfo;
import org.eclipse.statet.ltk.refactoring.core.RefactoringAdapter;
import org.eclipse.statet.r.core.IRCoreAccess;
import org.eclipse.statet.r.core.RCodeStyleSettings;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.model.IRSourceUnit;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.rlang.RTerminal;
import org.eclipse.statet.r.core.rsource.IRSourceConstants;
import org.eclipse.statet.r.core.rsource.RLexer;
import org.eclipse.statet.r.core.rsource.RSourceIndenter;
import org.eclipse.statet.r.core.rsource.ast.Assignment;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.core.rsource.ast.RScanner;
import org.eclipse.statet.r.core.rsource.ast.SourceComponent;
import org.eclipse.statet.r.core.source.IRDocumentConstants;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;


/**
 * RefactoringAdapter for R
 */
public class RRefactoringAdapter extends RefactoringAdapter {
	
	
	private RLexer lexer;
	
	
	public RRefactoringAdapter() {
		super(RModel.R_TYPE_ID);
	}
	
	
	@Override
	public String getPluginIdentifier() {
		return RCore.BUNDLE_ID;
	}
	
	@Override
	public RHeuristicTokenScanner getScanner(final ISourceUnit su) {
		return RHeuristicTokenScanner.create(su.getDocumentContentInfo());
	}
	
	@Override
	public boolean isCommentContent(final ITypedRegion partition) {
		return (partition != null
				&& partition.getType() == IRDocumentConstants.R_COMMENT_CONTENT_TYPE );
	}
	
	public TextRegion trimToAstRegion(final AbstractDocument document, final TextRegion region,
			final RHeuristicTokenScanner scanner) {
		scanner.configure(document, IRDocumentConstants.R_CODE_CONTENT_CONSTRAINT);
		int start= region.getStartOffset();
		int stop= region.getEndOffset();
		int result;
		
		while (stop > start) {
			result= scanner.findNonBlankBackward(stop, start, true);
			if (result >= 0) {
				if (scanner.getChar() == ';') {
					stop= result;
					continue;
				}
				else {
					stop= result + 1;
					break;
				}
			}
			else {
				stop= start;
				break;
			}
		}
		
		while (start < stop) {
			result= scanner.findNonBlankForward(start, stop, true);
			if (result >= 0) {
				if (scanner.getChar() == ';') {
					start= result + 1;
					continue;
				}
				else {
					start= result;
					break;
				}
			}
			else {
				start= stop;
				break;
			}
		}
		
		return new BasicTextRegion(start, stop);
	}
	
	public RAstNode searchPotentialNameNode(final ISourceUnit su, TextRegion region,
			final boolean allowAssignRegion, final IProgressMonitor monitor) {
		final SubMonitor m= SubMonitor.convert(monitor, 5);
		
		su.connect(m.newChild(1));
		try {
			final AbstractDocument document= su.getDocument(m.newChild(1));
			final RHeuristicTokenScanner scanner= getScanner(su);
			
			region= trimToAstRegion(document, region, scanner);
			
			final ISourceUnitModelInfo modelInfo= su.getModelInfo(RModel.R_TYPE_ID,
					IModelManager.MODEL_FILE, m.newChild(1) );
			if (modelInfo != null) {
				final AstSelection astSelection= AstSelection.search(modelInfo.getAst().getRoot(),
						region.getStartOffset(), region.getEndOffset(),
						AstSelection.MODE_COVERING_SAME_LAST );
				if (astSelection.getCovering() instanceof RAstNode) {
					final RAstNode node= (RAstNode) astSelection.getCovering();
					return getPotentialNameNode(node, allowAssignRegion);
				}
			}
			return null;
		}
		finally {
			m.setWorkRemaining(1);
			su.disconnect(m.newChild(1));
		}
	}
	
	public TextRegion expandSelectionRegion(final AbstractDocument document, final TextRegion region,
			final TextRegion limit, final RHeuristicTokenScanner scanner) {
		scanner.configure(document, new IPartitionConstraint() {
			@Override
			public boolean matches(final String partitionType) {
				return (partitionType != IRDocumentConstants.R_COMMENT_CONTENT_TYPE);
			}
		});
		final int min= limit.getStartOffset();
		final int max= limit.getEndOffset();
		int start= region.getStartOffset();
		int end= region.getEndOffset();
		int result;
		
		while (start > min) {
			result= scanner.findNonBlankBackward(start, min, true);
			if (result >= 0) {
				if (IRDocumentConstants.R_DEFAULT_CONTENT_CONSTRAINT.matches(scanner.getPartition(result).getType())
						&& scanner.getChar() == ';') {
					start= result;
					continue;
				}
				else {
					start= result + 1;
					break;
				}
			}
			else {
				start= min;
				break;
			}
		}
		
		while (end < max) {
			result= scanner.findNonBlankForward(end, max, true);
			if (result >= 0) {
				if (IRDocumentConstants.R_DEFAULT_CONTENT_CONSTRAINT.matches(scanner.getPartition(result).getType())
						&& scanner.getChar() == ';') {
					end= result + 1;
					continue;
				}
				else {
					end= result;
					break;
				}
			}
			else {
				end= max;
				break;
			}
		}
		
		return new BasicTextRegion(start, end);
	}
	
	
	public String validateIdentifier(final String value, final String identifierMessageName) {
		if (value == null || value.isEmpty()) { 
			return (identifierMessageName != null) ?
					NLS.bind(Messages.RIdentifiers_error_EmptyFor_message, identifierMessageName, Messages.RIdentifiers_error_Empty_message) :
					Messages.RIdentifiers_error_Empty_message;
		}
		if (this.lexer == null) {
			this.lexer= new RLexer();
		}
		this.lexer.reset(new StringParserInput(value).init());
		final RTerminal nextToken= this.lexer.next();
		if (nextToken == RTerminal.EOF) {
			return (identifierMessageName != null) ?
					NLS.bind(Messages.RIdentifiers_error_EmptyFor_message, identifierMessageName, Messages.RIdentifiers_error_Empty_message) :
					Messages.RIdentifiers_error_Empty_message;
		}
		if ((nextToken != RTerminal.SYMBOL && nextToken != RTerminal.SYMBOL_G)
				|| ((this.lexer.getFlags() & IRSourceConstants.STATUSFLAG_REAL_ERROR) != 0)
				|| (this.lexer.next() != RTerminal.EOF)) {
			return (identifierMessageName != null) ?
					NLS.bind(Messages.RIdentifiers_error_InvalidFor_message, identifierMessageName, Messages.RIdentifiers_error_Empty_message) :
					Messages.RIdentifiers_error_Invalid_message;
		}
		return null;
	}
	
	static RAstNode getPotentialNameNode(final RAstNode node, final boolean allowAssignRegion) {
		switch (node.getNodeType()) {
		case A_LEFT:
		case A_RIGHT:
		case A_EQUALS:
		case A_COLON:
			if (allowAssignRegion) {
				final Assignment assignment= (Assignment) node;
				if (assignment.isSearchOperator()) {
					switch (assignment.getTargetChild().getNodeType()) {
					case SYMBOL:
					case STRING_CONST:
						return assignment.getTargetChild();
					default:
						break;
					}
				}
			}
			return null;
		case SYMBOL:
		case STRING_CONST:
			return node;
		default:
			return null;
		}
	}
	
	public static String getQuotedIdentifier(final String identifier) {
		int length;
		if (identifier == null || (length= identifier.length()) == 0) {
			return "";
		}
		if (identifier.charAt(0) == '`') {
			if (length > 1 && identifier.charAt(length - 1) == '`') {
				return identifier;
			}
			else {
				return identifier + '`';
			}
		}
		else {
			return '`' + identifier + '`';
		}
	}
	
	public static String getUnquotedIdentifier(final String identifier) {
		int length;
		if (identifier == null || (length= identifier.length()) == 0) {
			return "";
		}
		if (identifier.charAt(0) == '`') {
			if (length > 1 && identifier.charAt(length - 1) == '`') {
				return identifier.substring(1, length - 2);
			}
			else {
				return identifier.substring(1, length - 1);
			}
		}
		else {
			return identifier;
		}
	}
	
	static String indent(final StringBuilder sb, final AbstractDocument orgDoc, final int offset,
			final ISourceUnit su, final RHeuristicTokenScanner scanner) throws BadLocationException, CoreException {
		final IRCoreAccess coreConfig= (su instanceof IRSourceUnit) ? ((IRSourceUnit) su).getRCoreAccess() : RCore.getWorkbenchAccess();
		
		final IndentUtil indentUtil= new IndentUtil(orgDoc, coreConfig.getRCodeStyle());
		final int column= indentUtil.getColumn(offset);
		final String initial= indentUtil.createIndentString(column);
		final String prefix= initial + "1\n"; //$NON-NLS-1$
		sb.insert(0, prefix);
		String text= sb.toString();
		final Document doc= new Document(text);
		final TextParserInput parseInput= new StringParserInput(text);
		text= null;
		
		final RScanner astScanner= new RScanner(AstInfo.LEVEL_MINIMAL);
		final SourceComponent rootNode= astScanner.scanSourceUnit(parseInput.init());
		
		final RSourceIndenter indenter= new RSourceIndenter(scanner, coreConfig);
		final TextEdit edits= indenter.getIndentEdits(doc, rootNode, 0, 1, doc.getNumberOfLines() - 1);
		edits.apply(doc, 0);
		return doc.get(prefix.length(), doc.getLength() - prefix.length());
	}
	
	/**
	 * Prepare the insertion of a command (text) before another command (offset)
	 * 
	 * The method prepares the insertion by modifying the text and returning the offset
	 * where to insert the modified text
	 * 
	 * @param text the command to insert, will be modified
	 * @param orgDoc the document
	 * @param offset the offset where to insert the command
	 * @param su the source unit, if available
	 * @return the offset to insert the modified text
	 * @throws BadLocationException
	 * @throws CoreException
	 */
	static int prepareInsertBefore(final StringBuilder text, final AbstractDocument orgDoc, final int offset,
			final ISourceUnit su) throws BadLocationException, CoreException {
		final IRCoreAccess coreConfig= (su instanceof IRSourceUnit) ? ((IRSourceUnit) su).getRCoreAccess() : RCore.getWorkbenchAccess();
		
		final IndentUtil indentUtil= new IndentUtil(orgDoc, coreConfig.getRCodeStyle());
		final int line= orgDoc.getLineOfOffset(offset);
		final int[] lineIndent= indentUtil.getLineIndent(line, false);
		if (lineIndent[IndentUtil.OFFSET_IDX] == offset) { // first char/command in line
			text.insert(0, indentUtil.createIndentString(lineIndent[IndentUtil.COLUMN_IDX]));
			text.append(orgDoc.getDefaultLineDelimiter());
			return orgDoc.getLineOffset(line);
		}
		else {
			text.append("; "); //$NON-NLS-1$
			return offset;
		}
	}
	
	static RCodeStyleSettings getCodeStyle(final ISourceUnit su) {
		if (su instanceof IRSourceUnit) {
			return ((IRSourceUnit) su).getRCoreAccess().getRCodeStyle();
		}
		return RCore.getWorkbenchAccess().getRCodeStyle();
	}
	
}
