/*=============================================================================#
 # Copyright (c) 2008, 2020 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.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
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.GroupCategory;
import org.eclipse.ltk.core.refactoring.GroupCategorySet;
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.ReplaceEdit;

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

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.core.LTK;
import org.eclipse.statet.ltk.model.core.ElementSet;
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.RCore;
import org.eclipse.statet.r.core.RUtil;
import org.eclipse.statet.r.core.model.IRFrame;
import org.eclipse.statet.r.core.model.IRFrameInSource;
import org.eclipse.statet.r.core.model.IRModelInfo;
import org.eclipse.statet.r.core.model.IRModelManager;
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.RTerminal;
import org.eclipse.statet.r.core.rsource.ast.GenericVisitor;
import org.eclipse.statet.r.core.rsource.ast.NodeType;
import org.eclipse.statet.r.core.rsource.ast.RAst;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;

public class RenameInRegionRefactoring extends Refactoring {
	
	
	private class VariableSearcher extends GenericVisitor {
		
		private final int start= RenameInRegionRefactoring.this.selectionRegion.getStartOffset();
		private final int stop= RenameInRegionRefactoring.this.selectionRegion.getEndOffset();
		
		@Override
		public void visitNode(final RAstNode node) throws InvocationTargetException {
			if (node.getStartOffset() >= this.stop || node.getEndOffset() < this.start) {
				return;
			}
			final List<Object> attachments= node.getAttachments();
			for (final Object attachment : attachments) {
				if (attachment instanceof RElementAccess) {
					final RElementAccess access= (RElementAccess) attachment;
					if (access.getType() != RElementName.MAIN_DEFAULT) {
						continue;
					}
					final RAstNode nameNode= access.getNameNode();
					if (nameNode != null
							&& nameNode.getStartOffset() >= this.start && nameNode.getEndOffset() <= this.stop) {
						add(access);
					}
				}
			}
			node.acceptInRChildren(this);
		}
		
		private void add(final RElementAccess access) {
			final IRFrame frame= access.getFrame();
			if (!(frame instanceof IRFrameInSource)
					|| frame.getFrameType() == IRFrame.PACKAGE) {
				return;
			}
			Map<String, Variable> map= RenameInRegionRefactoring.this.variablesList.get(frame);
			if (map == null) {
				map= new HashMap<>();
				RenameInRegionRefactoring.this.variablesList.put(frame, map);
			}
			final String name= access.getSegmentName();
			Variable variable= map.get(name);
			if (variable == null) {
				variable= new Variable(frame, name);
				map.put(name, variable);
			}
			variable.accessList.add(access);
		}
		
	}
	
	public class Variable {
		
		
		private final Object parent;
		
		private final String name;
		private String newName;
		
		private final List<RElementAccess> accessList;
		
		private Map<String, Variable> subVariables= Collections.emptyMap();
		
		public Variable(final Object parent, final String name) {
			this.parent= parent;
			this.name= name;
			this.accessList= new ArrayList<>();
		}
		
		
		public Object getParent() {
			return this.parent;
		}
		
		public String getName() {
			return this.name;
		}
		
		public String getNewName() {
			return this.newName;
		}
		
		public void setNewName(final String name) {
			if (!this.name.equals(name)) {
				this.newName= name;
			}
			else {
				this.newName= null;
			}
		}
		
		public int getOccurrencesCount() {
			return this.accessList.size();
		}
		
		
		public Map<String, Variable> getSubVariables() {
			return this.subVariables;
		}
		
	}
	
	
	private final RRefactoringAdapter adapter= new RRefactoringAdapter();
	private final ElementSet elementSet;
	
	private TextRegion selectionRegion;
	
	private final IRSourceUnit sourceUnit;
	
	private Map<IRFrame, Map<String, Variable>> variablesList;
	
	
	/**
	 * Creates a new rename refactoring.
	 * @param su the source unit
	 * @param region (selected) region
	 */
	public RenameInRegionRefactoring(final IRSourceUnit su, final TextRegion region) {
		this.sourceUnit= su;
		this.elementSet= new ElementSet(new Object[] { su });
		
		if (region != null && region.getStartOffset() >= 0 && region.getLength() >= 0) {
			this.selectionRegion= region;
		}
	}
	
	
	@Override
	public String getName() {
		return Messages.RenameInRegion_label;
	}
	
	public String getIdentifier() {
		return RRefactoring.RENAME_IN_REGION_REFACTORING_ID;
	}
	
	public Map<IRFrame, Map<String, Variable>> getVariables() {
		return this.variablesList;
	}
	
	
	@Override
	public RefactoringStatus checkInitialConditions(final IProgressMonitor monitor) throws CoreException {
		final SubMonitor m= SubMonitor.convert(monitor, 6);
		RAstNode rootNode= null;
		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 IRModelInfo modelInfo= (IRModelInfo) this.sourceUnit.getModelInfo(RModel.R_TYPE_ID, IRModelManager.MODEL_FILE, m.newChild(1));
					if (modelInfo != null) {
						final TextRegion region= this.adapter.trimToAstRegion(document,
								this.selectionRegion, scanner );
						final AstInfo ast= modelInfo.getAst();
						if (ast != null) {
							rootNode= (RAstNode) AstSelection.search(ast.getRoot(),
									region.getStartOffset(), region.getEndOffset(),
									AstSelection.MODE_COVERING_SAME_LAST ).getCovering();
						}
					}
				}
				finally {
					this.sourceUnit.disconnect(m.newChild(1));
				}
			}
			
			if (rootNode == null) {
				return RefactoringStatus.createFatalErrorStatus(Messages.ExtractTemp_error_InvalidSelection_message);
			}
			final RefactoringStatus result= new RefactoringStatus();
			this.adapter.checkInitialToModify(result, this.elementSet);
			m.worked(1);
			
			if (result.hasFatalError()) {
				return result;
			}
			
			searchVariables(rootNode, result);
			m.worked(2);
			return result;
		}
		finally {
			m.done();
		}
	}
	
	private void searchVariables(final RAstNode rootNode, final RefactoringStatus result) {
		this.variablesList= new HashMap<>();
		final VariableSearcher searcher= new VariableSearcher();
		try {
			rootNode.acceptInR(searcher);
		}
		catch (final InvocationTargetException e) {}
		for (final Map<String, Variable> map : this.variablesList.values()) {
			for (final Variable var : map.values()) {
				checkVariables(var);
			}
		}
	}
	
	private void checkVariables(final Variable var) {
		Map<String, RenameInRegionRefactoring.Variable> map= null;
		for (final RElementAccess access : var.accessList) {
			final RElementAccess next= access.getNextSegment();
			if (next != null && next.getSegmentName() != null
					&& (next.getType() == RElementName.SUB_NAMEDPART
							|| next.getType() == RElementName.SUB_NAMEDSLOT )) {
				if (map == null) {
					map= new HashMap<>();
				}
				Variable sub= map.get(next.getSegmentName());
				if (sub == null) {
					sub= new Variable(var, next.getSegmentName());
					map.put(next.getSegmentName(), sub);
				}
				next.getSegmentName();
				next.getFrame();
				sub.accessList.add(next);
			}
		}
		if (map != null) {
			var.subVariables= map;
		}
	}
	
	
	@Override
	public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor) throws CoreException {
		final SubMonitor m= SubMonitor.convert(monitor, RefactoringMessages.Common_FinalCheck_label, 3);
		try {
			final RefactoringStatus status= new RefactoringStatus();
			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);
			}
			final List<String> variableNames= createChanges(textFileChange, m.newChild(2));
			
			final Map<String, String> arguments= new HashMap<>();
			final String description= NLS.bind(Messages.RenameInRegion_Descriptor_description,
					RUtil.formatVarNames(variableNames));
			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);
			m.worked(1);
			
			return new RefactoringChange(descriptor,
					Messages.RenameInRegion_label,
					new Change[] { textFileChange });
		}
		catch (final BadLocationException e) {
			throw new CoreException(new Status(IStatus.ERROR, RCore.BUNDLE_ID, "Unexpected error (concurrent change?)", e));
		}
		finally {
			monitor.done();
		}
	}
	
	private List<String> createChanges(final TextFileChange change, final SubMonitor m) throws BadLocationException {
		m.setWorkRemaining(2 + 8);
		
		final List<String> names= new ArrayList<>();
		
		this.sourceUnit.connect(m.newChild(1));
		try {
			final SubMonitor m1= m.newChild(8).setWorkRemaining(this.variablesList.size());
			for (final Map<String, Variable> frameList : this.variablesList.values()) {
				createMainChanges(frameList, change, names);
				m1.worked(1);
			}
			return names;
		}
		finally {
			this.sourceUnit.disconnect(m.newChild(1));
		}
	}
	
	private void createMainChanges(final Map<String, Variable> frameList,
			final TextFileChange change, final List<String> names) {
		for (final Variable variable : frameList.values()) {
			if (variable.newName != null) {
				final String oldName= RRefactoringAdapter.getUnquotedIdentifier(variable.name);
				final String oldMsgName= RUtil.formatVarName(oldName);
				final boolean isQuoted= (variable.newName.charAt(0) == '`');
				final GroupCategorySet set= new GroupCategorySet(new GroupCategory(
						((IRFrameInSource) variable.getParent()).getFrameId() + '$' + variable.name,
						NLS.bind(Messages.RenameInRegion_Changes_VariableGroup_name, oldMsgName), "")); //$NON-NLS-1$
				final String message= NLS.bind(Messages.RenameInRegion_Changes_ReplaceOccurrence_name,
						oldMsgName);
				
				for (final RElementAccess access : variable.accessList) {
					final RAstNode nameNode= access.getNameNode();
					if (nameNode == null) {
						continue;
					}
					final String text= (isQuoted && nameNode.getNodeType() == NodeType.SYMBOL && nameNode.getOperator(0) == RTerminal.SYMBOL) ?
							variable.newName : RRefactoringAdapter.getUnquotedIdentifier(variable.newName);
					final TextRegion nameRegion= RAst.getElementNameRegion(nameNode);
					TextChangeCompatibility.addTextEdit(change, message,
							new ReplaceEdit(nameRegion.getStartOffset(), nameRegion.getLength(), text),
							set );
					
				}
				names.add(oldName);
			}
			if (!variable.subVariables.isEmpty()) {
				createSubChanges(variable, change, names);
			}
		}
	}
	
	private void createSubChanges(final Variable parent, final TextFileChange change, final List<String> names) {
		final String parentMsgName= RUtil.formatVarName(
				RRefactoringAdapter.getUnquotedIdentifier(parent.name) );
		for (final Variable variable : parent.subVariables.values()) {
			if (variable.newName != null) {
				final String oldName= RRefactoringAdapter.getUnquotedIdentifier(variable.name);
				final String oldMsgName= RUtil.formatVarName(oldName);
				final boolean isQuoted= (variable.newName.charAt(0) == '`');
				final GroupCategorySet set= new GroupCategorySet(new GroupCategory(
						((IRFrameInSource) parent.getParent()).getFrameId() + '$' + parent.name,
						NLS.bind(Messages.RenameInRegion_Changes_VariableGroup_name, parentMsgName), "")); //$NON-NLS-1$
				final String message= NLS.bind(Messages.RenameInRegion_Changes_ReplaceOccurrenceOf_name,
						oldMsgName, parentMsgName );
				
				for (final RElementAccess access : variable.accessList) {
					final RAstNode nameNode= access.getNameNode();
					if (nameNode == null) {
						continue;
					}
					final String text= (isQuoted && nameNode.getNodeType() == NodeType.SYMBOL && nameNode.getOperator(0) == RTerminal.SYMBOL) ?
							variable.newName : RRefactoringAdapter.getUnquotedIdentifier(variable.newName);
					final TextRegion nameRegion= RAst.getElementNameRegion(nameNode);
					TextChangeCompatibility.addTextEdit(change, message,
							new ReplaceEdit(nameRegion.getStartOffset(), nameRegion.getLength(), text),
							set );
				}
				names.add(oldName);
			}
		}
	}
	
}
