/*=============================================================================#
 # Copyright (c) 2008, 2021 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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.osgi.util.NLS;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;

import org.eclipse.statet.jcommons.text.core.BasicTextRegion;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.internal.r.core.refactoring.Messages;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.core.Ltk;
import org.eclipse.statet.ltk.model.core.ElementSet;
import org.eclipse.statet.ltk.model.core.LtkModelUtils;
import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
import org.eclipse.statet.ltk.refactoring.core.CommonRefactoringDescriptor;
import org.eclipse.statet.ltk.refactoring.core.RefactoringChange;
import org.eclipse.statet.ltk.refactoring.core.RefactoringMessages;
import org.eclipse.statet.ltk.refactoring.core.SourceUnitChange;
import org.eclipse.statet.ltk.refactoring.core.TextChangeCompatibility;
import org.eclipse.statet.r.core.RCodeStyleSettings;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.RUtil;
import org.eclipse.statet.r.core.model.ArgsDefinition;
import org.eclipse.statet.r.core.model.ArgsDefinition.Arg;
import org.eclipse.statet.r.core.model.RElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.model.RLangMethod;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RModelManager;
import org.eclipse.statet.r.core.model.RSourceUnit;
import org.eclipse.statet.r.core.model.RSourceUnitModelInfo;
import org.eclipse.statet.r.core.rlang.RTerminal;
import org.eclipse.statet.r.core.rsource.ast.FDef;
import org.eclipse.statet.r.core.rsource.ast.NodeType;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.core.rsource.ast.RAsts;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;

public class FunctionToS4MethodRefactoring extends Refactoring {
	
	
	public class Variable {
		
		
		private final Arg arg;
		private boolean asGenericArgument;
		private boolean asGenericArgumentDefault;
		private String argumentType;
		
		
		public Variable(final Arg arg) {
			this.arg= arg;
		}
		
		
		void init(final boolean enable) {
			this.asGenericArgumentDefault= this.asGenericArgument= enable;
		}
		
		public String getName() {
			return  (this.arg.name != null) ? this.arg.name : ""; //$NON-NLS-1$
		}
		
		public boolean getUseAsGenericArgumentDefault() {
			return this.asGenericArgumentDefault;
		}
		
		public boolean getUseAsGenericArgument() {
			return this.asGenericArgument;
		}
		
		public void setUseAsGenericArgument(final boolean enable) {
			this.asGenericArgument= enable;
		}
		
		public String getArgumentType() {
			return this.argumentType;
		}
		
		public void setArgumentType(final String typeName) {
			if (typeName != null && typeName.trim().length() > 0) {
				this.argumentType= typeName;
			}
			else {
				this.argumentType= null;
			}
		}
		
	}
	
	
	private final RRefactoringAdapter adapter= new RRefactoringAdapter();
	private final ElementSet elementSet;
	
	private TextRegion selectionRegion;
	private TextRegion operationRegion;
	
	private final RSourceUnit sourceUnit;
	private RLangMethod function;
	
//	private RAstNode container;
	private List<Variable> variablesList;
	private String functionName= ""; //$NON-NLS-1$
	private boolean generateGeneric= true;
	
	
	/**
	 * Creates a new converting refactoring.
	 * @param su the source unit
	 * @param region (selected) region of the function to convert
	 */
	public FunctionToS4MethodRefactoring(final RSourceUnit su, final TextRegion selection) {
		this.sourceUnit= su;
		this.elementSet= new ElementSet(new Object[] { su });
		
		if (selection != null && selection.getStartOffset() >= 0 && selection.getLength() >= 0) {
			this.selectionRegion= selection;
		}
	}
	
	
	@Override
	public String getName() {
		return Messages.FunctionToS4Method_label;
	}
	
	public String getIdentifier() {
		return RRefactoring.EXTRACT_FUNCTION_REFACTORING_ID;
	}
	
	
	public void setFunctionName(final String newName) {
		this.functionName= newName;
	}
	
	public String getFunctionName() {
		return this.functionName;
	}
	
	public List<Variable> getVariables() {
		return this.variablesList;
	}
	
	public void setGenerateGeneric(final boolean enable) {
		this.generateGeneric= enable;
	}
	
	public boolean getGenerateGeneric() {
		return this.generateGeneric;
	}
	
	@Override
	public RefactoringStatus checkInitialConditions(final IProgressMonitor monitor) throws CoreException {
		final SubMonitor m= SubMonitor.convert(monitor, 6);
		try {
			if (this.selectionRegion != null) {
				this.sourceUnit.connect(m.newChild(1));
				try {
					final AbstractDocument document= this.sourceUnit.getDocument(monitor);
					final RHeuristicTokenScanner scanner= this.adapter.getScanner(this.sourceUnit);
					
					final RSourceUnitModelInfo modelInfo= (RSourceUnitModelInfo)this.sourceUnit.getModelInfo(RModel.R_TYPE_ID, RModelManager.MODEL_FILE, m.newChild(1));
					if (modelInfo != null) {
						final TextRegion region= this.adapter.trimToAstRegion(document,
								this.selectionRegion, scanner );
						SourceStructElement element= LtkModelUtils.getCoveringSourceElement(
								modelInfo.getSourceElement(), region );
						while (element != null) {
							if (element instanceof RLangMethod) {
								this.function= (RLangMethod)element;
								break;
							}
							element= element.getSourceParent();
						}
					}
					
					if (this.function != null) {
						final SourceStructElement source= (SourceStructElement) this.function;
						this.operationRegion= this.adapter.expandSelectionRegion(document,
								source.getSourceRange(), this.selectionRegion, scanner );
					}
				}
				finally {
					this.sourceUnit.disconnect(m.newChild(1));
				}
			}
			
			if (this.function == null) {
				return RefactoringStatus.createFatalErrorStatus(Messages.FunctionToS4Method_error_InvalidSelection_message);
			}
			final RefactoringStatus result= new RefactoringStatus();
			this.adapter.checkInitialToModify(result, this.elementSet);
			m.worked(1);
			
			if (result.hasFatalError()) {
				return result;
			}
			
			checkFunction(result);
			m.worked(2);
			return result;
		}
		finally {
			m.done();
		}
	}
	
	private void checkFunction(final RefactoringStatus result) {
		if ((this.function.getElementType() & RElement.MASK_C2) != RElement.R_COMMON_FUNCTION
				&& (this.function.getElementType() & RElement.MASK_C2) != RElement.R_COMMON_FUNCTION) {
			result.merge(RefactoringStatus.createFatalErrorStatus(Messages.FunctionToS4Method_error_SelectionAlreadyS4_message));
			return;
		}
		final RAstNode node= (RAstNode) this.function.getAdapter(AstNode.class);
		if (RAsts.hasErrors(node)) {
			result.merge(RefactoringStatus.createWarningStatus(Messages.FunctionToS4Method_warning_SelectionSyntaxError_message));
		}
//		if (fSelectionRegion != null
//				&& (fSelectionRegion.getOffset() != this.operationRegion.getOffset()
//						|| this.selectionRegion.getLength() != this.operationRegion.getLength() )) {
//			result.merge(RefactoringStatus.createWarningStatus("The selected code does not equal exactly the found expression(s)."));
//		}
		
		final RElementName elementName= this.function.getElementName().getLastSegment();
		this.functionName= elementName.getDisplayName();
		
		final ArgsDefinition argsDef= this.function.getArgsDefinition();
		final int count= (argsDef != null) ? argsDef.size() : 0;
		this.variablesList= new ArrayList<>(count);
		boolean dots= false;
		for (int i= 0; i < count; i++) {
			final Arg arg= argsDef.get(i);
			final Variable variable= new Variable(arg);
			if (variable.getName().equals(RTerminal.S_ELLIPSIS)) {
				dots= true;
				variable.init(true);
			}
			else {
				variable.init(!dots);
			}
			this.variablesList.add(variable);
		}
	}
	
	public RefactoringStatus checkFunctionName(final String newName) {
		if (newName == null || newName.isEmpty()) {
			return RefactoringStatus.createFatalErrorStatus(
					NLS.bind(Messages.RIdentifiers_error_EmptyFor_message, "The function name"));
		}
		return new RefactoringStatus();
	}
	
	
	@Override
	public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor) throws CoreException {
		final SubMonitor m= SubMonitor.convert(monitor, RefactoringMessages.Common_FinalCheck_label, 3);
		try {
			final RefactoringStatus status= checkFunctionName(this.functionName);
			this.adapter.checkFinalToModify(status, this.elementSet, m.newChild(2));
			return status;
		}
		finally {
			m.done();
		}
	}
	
	@Override
	public Change createChange(final IProgressMonitor monitor) throws CoreException {
		final SubMonitor m= SubMonitor.convert(monitor, RefactoringMessages.Common_CreateChanges_label, 3);
		try {
			
			final TextFileChange textFileChange= new SourceUnitChange(this.sourceUnit);
			if (this.sourceUnit.getWorkingContext() == Ltk.EDITOR_CONTEXT) {
				textFileChange.setSaveMode(TextFileChange.LEAVE_DIRTY);
			}
			createChanges(textFileChange, m.newChild(2));
			
			final Map<String, String> arguments= new HashMap<>();
			final String varName= RRefactoringAdapter.getUnquotedIdentifier(this.functionName);
			final String description= NLS.bind(Messages.FunctionToS4Method_Descriptor_description,
					RUtil.formatVarName(varName) );
			final IProject resource= this.elementSet.getSingleProject();
			final String project= (resource != null) ? resource.getName() : null;
			final String source= (project != null) ? NLS.bind(RefactoringMessages.Common_Source_Project_label, project) : RefactoringMessages.Common_Source_Workspace_label;
			final int flags= 0;
			final String comment= ""; //$NON-NLS-1$
			final CommonRefactoringDescriptor descriptor= new CommonRefactoringDescriptor(
					getIdentifier(), project, description, comment, arguments, flags);
			
			return new RefactoringChange(descriptor,
					Messages.FunctionToS4Method_label, 
					new Change[] { textFileChange });
		}
		catch (final BadLocationException e) {
			throw new CoreException(new Status(IStatus.ERROR, RCore.BUNDLE_ID, "Unexpected error (concurrent change?)", e));
		}
		finally {
			m.done();
		}
	}
	
	private void createChanges(final TextFileChange change, final SubMonitor m) throws BadLocationException, CoreException {
		m.setWorkRemaining(3 + 3 * 4);
		
		this.sourceUnit.connect(m.newChild(1));
		try {
			final AbstractDocument document= this.sourceUnit.getDocument(m.newChild(1));
			final RHeuristicTokenScanner scanner= this.adapter.getScanner(this.sourceUnit);
			final RCodeStyleSettings codeStyle= RRefactoringAdapter.getCodeStyle(this.sourceUnit);
			final StringBuilder sb= new StringBuilder();
			
			final String nl= document.getDefaultLineDelimiter();
			final String argAssign= codeStyle.getArgAssignString();
			
			RAstNode firstParentChild= (RAstNode) this.function.getAdapter(AstNode.class);
			while (true) {
				final RAstNode parent= firstParentChild.getRParent();
				if (parent == null
						|| parent.getNodeType() == NodeType.SOURCELINES || parent.getNodeType() == NodeType.BLOCK) {
					break;
				}
				firstParentChild= parent;
			}
			
			final TextRegion region= this.adapter.expandWhitespaceBlock(document, this.operationRegion, scanner);
			final int insertOffset= this.adapter.expandWhitespaceBlock(document,
					this.adapter.expandSelectionRegion(document,
							new BasicTextRegion(firstParentChild.getStartOffset()), this.operationRegion, scanner ),
					scanner ).getStartOffset();
			final FDef fdefNode= this.function.getAdapter(FDef.class);
			final TextRegion fbodyRegion= this.adapter.expandWhitespaceBlock(document,
					this.adapter.expandSelectionRegion(document,
							fdefNode.getContChild(), this.operationRegion, scanner ),
					scanner );
			
			{	TextChangeCompatibility.addTextEdit(change, Messages.FunctionToS4Method_Changes_DeleteOld_name,
						new DeleteEdit(region.getStartOffset(), region.getLength()));
				m.worked(4);
			}
			{	sb.setLength(0);
				sb.append("setGeneric(\""); //$NON-NLS-1$
				sb.append(this.functionName);
				sb.append("\","); //$NON-NLS-1$
				sb.append(nl);
				sb.append("function("); //$NON-NLS-1$
				boolean dots= false;
				for (final Variable variable : this.variablesList) {
					if (variable.getName().equals(RTerminal.S_ELLIPSIS)) {
						dots= true;
					}
					if (variable.getUseAsGenericArgument()) {
						sb.append(RElementName.create(RElementName.MAIN_DEFAULT, variable.getName()).getDisplayName());
						sb.append(", "); //$NON-NLS-1$
					}
				}
				if (!dots) {
					sb.append("..., "); //$NON-NLS-1$
				}
				sb.delete(sb.length() - 2, sb.length());
				sb.append(')');
				if (codeStyle.getNewlineFDefBodyBlockBefore()) {
					sb.append(nl);
				}
				else {
					sb.append(' ');
				}
				sb.append('{');
				sb.append(nl);
				sb.append("standardGeneric(\""); //$NON-NLS-1$
				sb.append(this.functionName);
				sb.append("\")"); //$NON-NLS-1$
				sb.append(nl);
				sb.append("})"); //$NON-NLS-1$
				sb.append(nl);
				sb.append(nl);
				final String genericDef= RRefactoringAdapter.indent(sb, document,
						firstParentChild.getStartOffset(),
						this.sourceUnit, scanner );
				TextChangeCompatibility.addTextEdit(change, Messages.FunctionToS4Method_Changes_AddGenericDef_name,
						new InsertEdit(insertOffset, genericDef));
				m.worked(4);
			}
			{	sb.setLength(0);
				sb.append("setMethod(\""); //$NON-NLS-1$
				sb.append(this.functionName);
				sb.append("\","); //$NON-NLS-1$
				sb.append(nl);
				sb.append("signature("); //$NON-NLS-1$
				boolean hasType= false;
				for (final Variable variable : this.variablesList) {
					if (variable.getUseAsGenericArgument() && variable.getArgumentType() != null) {
						hasType= true;
						sb.append(RElementName.create(RElementName.MAIN_DEFAULT, variable.getName()).getDisplayName());
						sb.append(argAssign);
						sb.append("\""); //$NON-NLS-1$
						sb.append(variable.getArgumentType());
						sb.append("\", "); //$NON-NLS-1$
					}
				}
				if (hasType) {
					sb.delete(sb.length() - 2, sb.length());
				}
				sb.append("),"); //$NON-NLS-1$
				sb.append(nl);
				sb.append("function("); //$NON-NLS-1$
				final FDef.Args argsNode= fdefNode.getArgsChild();
				for (final Variable variable : this.variablesList) {
					sb.append(RElementName.create(RElementName.MAIN_DEFAULT, variable.getName()).getDisplayName());
					final FDef.Arg argNode= argsNode.getChild(variable.arg.index);
					if (argNode.hasDefault()) {
						sb.append(argAssign);
						sb.append(document.get(argNode.getDefaultChild().getStartOffset(), argNode.getDefaultChild().getLength()));
					}
					sb.append(", "); //$NON-NLS-1$
				}
				if (!this.variablesList.isEmpty()) {
					sb.delete(sb.length() - 2, sb.length());
				}
				sb.append(')');
				if (codeStyle.getNewlineFDefBodyBlockBefore()
						|| fdefNode.getContChild().getNodeType() != NodeType.BLOCK) {
					sb.append(nl);
				}
				else {
					sb.append(' ');
				}
				sb.append(document.get(fbodyRegion.getStartOffset(), fbodyRegion.getLength()).trim());
				sb.append(")"); //$NON-NLS-1$
				sb.append(nl);
				final String methodDef= RRefactoringAdapter.indent(sb, document,
						firstParentChild.getStartOffset(),
						this.sourceUnit, scanner );
				TextChangeCompatibility.addTextEdit(change, Messages.FunctionToS4Method_Changes_AddMethodDef_name,
						new InsertEdit(insertOffset, methodDef));
				m.worked(4);
			}
		}
		finally {
			this.sourceUnit.disconnect(m.newChild(1));
		}
	}
	
}
