/*=============================================================================#
 # 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 java.util.Set;

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.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.ReplaceEdit;

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

import org.eclipse.statet.internal.r.core.refactoring.Messages;
import org.eclipse.statet.ltk.core.Ltk;
import org.eclipse.statet.ltk.model.core.ElementSet;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
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.ltk.refactoring.core.TextChangeManager;
import org.eclipse.statet.r.core.RProject;
import org.eclipse.statet.r.core.RUtil;
import org.eclipse.statet.r.core.model.RElementAccess;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.model.RFrame;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RModelManager;
import org.eclipse.statet.r.core.model.RSourceFrame;
import org.eclipse.statet.r.core.model.RSourceUnit;
import org.eclipse.statet.r.core.model.RSourceUnitModelInfo;
import org.eclipse.statet.r.core.model.RWorkspaceSourceUnit;
import org.eclipse.statet.r.core.refactoring.RElementSearchProcessor.Mode;
import org.eclipse.statet.r.core.rlang.RTerminal;
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;


public class RenameInWorkspaceRefactoring extends Refactoring {
	
	
	private static final int FOUND_NONE= 0;
	private static final int FOUND_READ= 1;
	private static final int FOUND_WRITE= 2;
	
	
	private class SearchProcessor extends RElementSearchProcessor {
		
		
		TextChangeManager changeManager;
		
		
		public SearchProcessor(final RElementName elementName,
				final RSourceUnit sourceUnit, final RElementAccess mainAccess) {
			super(elementName, sourceUnit, mainAccess, null, WARN_NO_DEFINITION);
		}
		
		
		@Override
		public void begin(final SubMonitor m) {
			this.changeManager= new TextChangeManager();
		}
		
		@Override
		public void beginFinalProcessing(final SubMonitor m) {
			m.subTask(RefactoringMessages.Common_CreateChanges_label);
			
			final RSourceUnit initialSu= getInitialSourceUnit();
			final TextFileChange textFileChange= this.changeManager.get(initialSu);
			if (initialSu.getWorkingContext() == Ltk.EDITOR_CONTEXT) {
				textFileChange.setSaveMode(TextFileChange.LEAVE_DIRTY);
			}
		}
		
		@Override
		public void process(final RProject project, final List<SourceUnit> sus,
				final SubMonitor m) throws BadLocationException {
			if (sus != null) {
				int workRemaining= sus.size();
				for (final SourceUnit su : sus) {
					m.setWorkRemaining(workRemaining--);
					final TextFileChange change= this.changeManager.get(su);
					createChanges(su, change, this.definitionFrameIds, m.newChild(1));
				}
			}
		}
		
	}
	
	
	private final RRefactoringAdapter adapter= new RRefactoringAdapter();
	private final ElementSet elementSet;
	
	private TextRegion selectionRegion;
	
	private final RWorkspaceSourceUnit sourceUnit;
	
	private RAstNode initialSymbolNode;
	private RElementAccess initialAccess;
	private SearchProcessor searchProcessor;
	
	private String newName;
	private Change[] changes;
	
	
	/**
	 * Creates a new rename refactoring
	 * 
	 * @param su the source unit
	 * @param region (selected) region of an occurrence of the variable
	 */
	public RenameInWorkspaceRefactoring(final RWorkspaceSourceUnit 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;
		}
	}
	
	/**
	 * Creates a new rename refactoring
	 * 
	 * @param su the source unit
	 * @param region (selected) region of an occurrence of the variable
	 */
	public RenameInWorkspaceRefactoring(final RWorkspaceSourceUnit su, final RAstNode node) {
		this.sourceUnit= su;
		this.elementSet= new ElementSet(new Object[] { su });
		
		if (node.getNodeType() == NodeType.SYMBOL || node.getNodeType() == NodeType.STRING_CONST) {
			this.initialSymbolNode= node;
		}
	}
	
	
	@Override
	public String getName() {
		return Messages.RenameInWorkspace_label;
	}
	
	public String getIdentifier() {
		return RRefactoring.RENAME_IN_WORKSPACE_REFACTORING_ID;
	}
	
	@Override
	public RefactoringStatus checkInitialConditions(final IProgressMonitor monitor) throws CoreException {
		final SubMonitor m= SubMonitor.convert(monitor, 6);
		try {
			if (this.selectionRegion != null) {
				this.initialSymbolNode= this.adapter.searchPotentialNameNode(this.sourceUnit,
						this.selectionRegion, false, m.newChild(4) );
				}
			if (this.initialSymbolNode == null) {
				return RefactoringStatus.createFatalErrorStatus(Messages.RenameInWorkspace_error_InvalidSelection_message);
			}
			if (this.sourceUnit.getResource() == null || this.sourceUnit.getResource().getProject() == null) {
				return RefactoringStatus.createFatalErrorStatus("The file is not in the workspace");
			}
			final RefactoringStatus result= new RefactoringStatus();
			this.adapter.checkInitialToModify(result, this.elementSet);
			if (result.hasFatalError()) {
				return result;
			}
			
			checkVariable(result);
			return result;
		}
		finally {
			m.done();
		}
	}
	
	private void checkVariable(final RefactoringStatus result) {
		this.initialAccess= RElementAccess.getMainElementAccessOfNameNode(this.initialSymbolNode);
		final RElementAccess subAccess= RElementAccess.getElementAccessOfNameNode(this.initialSymbolNode);
		final RElementName fullName= (this.initialAccess != null && subAccess != null) ?
				RElementName.create(this.initialAccess, subAccess.getNextSegment(), false) : null;
		this.searchProcessor= new SearchProcessor(fullName, this.sourceUnit, this.initialAccess);
		if (this.searchProcessor.getStatus().getSeverity() >= IStatus.ERROR) {
			result.merge(RefactoringStatus.create(this.searchProcessor.getStatus()));
			return;
		}
		
		this.newName= fullName.getDisplayName();
	}
	
	public String getCurrentName() {
		return this.searchProcessor.getElementName().getDisplayName();
	}
	
	public String getNewName() {
		return this.newName;
	}
	
	public RefactoringStatus checkNewName(final String name) {
		final String message= this.adapter.validateIdentifier(name, "The variable name");
		if (message != null) {
			return RefactoringStatus.createFatalErrorStatus(message);
		}
		return new RefactoringStatus();
	}
	
	public void setNewName(final String name) {
		this.newName= name;
	}
	
	public List<Mode> getAvailableModes() {
		return this.searchProcessor.getAvailableModes();
	}
	
	public Mode getMode() {
		return this.searchProcessor.getMode();
	}
	
	public void setMode(final Mode mode) {
		this.searchProcessor.setMode(mode);
	}
	
	@Override
	public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor) throws CoreException {
		final SubMonitor m= SubMonitor.convert(monitor, RefactoringMessages.Common_FinalCheck_label, 20 + 3);
		try {
			final RefactoringStatus status= checkNewName(this.newName);
			if (status.getSeverity() >= IStatus.ERROR) {
				return status;
			}
			
			if (getMode() == Mode.LOCAL_FRAME) {
				this.changes= createLocalChanges(m.newChild(20));
				
				this.adapter.checkFinalToModify(status, this.elementSet, m.newChild(2));
				return status;
			}
			else {
				this.searchProcessor.run(m.newChild(20));
				if (this.searchProcessor.getStatus() != Status.OK_STATUS) {
					status.merge(RefactoringStatus.create(this.searchProcessor.getStatus()));
				}
				final TextChangeManager changeManager= this.searchProcessor.changeManager;
				this.changes= changeManager.getAllChanges();
				m.worked(1);
				
				final ElementSet elements= new ElementSet(changeManager.getAllSourceUnits());
				this.adapter.checkFinalToModify(status, elements, 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 Map<String, String> arguments= new HashMap<>();
			final String description= NLS.bind(Messages.RenameInWorkspace_Descriptor_description,
					RUtil.formatVarName(getNewName()) );
			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.RenameInWorkspace_label, 
					this.changes);
		}
		finally {
			m.done();
		}
	}
	
	
	private Change[] createLocalChanges(final SubMonitor m) {
		m.setWorkRemaining(2 + 4);
		
		final TextFileChange change= new SourceUnitChange(this.sourceUnit);
		if (this.sourceUnit.getWorkingContext() == Ltk.EDITOR_CONTEXT) {
			change.setSaveMode(TextFileChange.LEAVE_DIRTY);
		}
		
		this.sourceUnit.connect(m.newChild(1));
		try {
			final ImList<? extends RElementAccess> accessList= this.initialAccess.getAllInUnit(false);
			
			final String unquoted= RRefactoringAdapter.getUnquotedIdentifier(this.newName);
			final String quoted= RRefactoringAdapter.getQuotedIdentifier(this.newName);
			final boolean isQuoted= (this.newName.charAt(0) == '`');
			
			for (final RElementAccess access : accessList) {
				final RAstNode nameNode= access.getNameNode();
				final String text= (isQuoted && nameNode.getNodeType() == NodeType.SYMBOL && nameNode.getOperator(0) == RTerminal.SYMBOL) ?
						this.newName : unquoted;
				final TextRegion nameRegion= RAsts.getElementNameRegion(nameNode);
				if (nameRegion != null) {
					TextChangeCompatibility.addTextEdit(change, Messages.RenameInWorkspace_Changes_ReplaceOccurrence_name,
							new ReplaceEdit(nameRegion.getStartOffset(), nameRegion.getLength(), text));
				}
			}
			m.worked(4);
			
			return new Change[] { change };
		}
		finally {
			this.sourceUnit.disconnect(m.newChild(1));
		}
	}
	
	
	private int createChanges(final SourceUnit su, final TextFileChange change,
			final Set<String> definitionFrameIds, final SubMonitor m) throws BadLocationException {
		m.setWorkRemaining(3 + 6);
		
		int found= FOUND_NONE;
		su.connect(m.newChild(1));
		try {
			final RSourceUnitModelInfo modelInfo= (RSourceUnitModelInfo)su.getModelInfo(RModel.R_TYPE_ID,
					RModelManager.MODEL_FILE, m.newChild(1) );
			
			final String unquoted= RRefactoringAdapter.getUnquotedIdentifier(this.newName);
			final String quoted= RRefactoringAdapter.getQuotedIdentifier(this.newName);
			final boolean isQuoted= (this.newName.charAt(0) == '`');
			
			final List<List<? extends RElementAccess>> allFrameAccess= new ArrayList<>();
			for (final String frameId : definitionFrameIds) {
				final RFrame frame;
				if (frameId == null) {
					frame= modelInfo.getTopFrame();
				}
				else {
					frame= modelInfo.getReferencedFrames().get(frameId);
				}
				if (frame instanceof RSourceFrame) {
					final List<? extends RElementAccess> allAccess= ((RSourceFrame)frame).getAllAccessOf(
							this.searchProcessor.mainName.getSegmentName(), false );
					if (allAccess != null && allAccess.size() > 0) {
						allFrameAccess.add(allAccess);
					}
				}
			}
			m.worked(2);
			
			for (final List<? extends RElementAccess> allAccess : allFrameAccess) {
				for (final RElementAccess access : allAccess) {
					found|= (access.isWriteAccess() && access.getNextSegment() == null) ? FOUND_WRITE : FOUND_READ;
					final RAstNode nameNode= access.getNameNode();
					final String text= (isQuoted && nameNode.getNodeType() == NodeType.SYMBOL && nameNode.getOperator(0) == RTerminal.SYMBOL) ?
							this.newName : unquoted;
					final TextRegion nameRegion= RAsts.getElementNameRegion(nameNode);
					if (nameRegion != null) {
						TextChangeCompatibility.addTextEdit(change, Messages.RenameInWorkspace_Changes_ReplaceOccurrence_name,
								new ReplaceEdit(nameRegion.getStartOffset(), nameRegion.getLength(), text));
					}
				}
			}
			m.worked(4);
			
			return found;
		}
		finally {
			su.disconnect(m.newChild(1));
		}
	}
	
}
