/*******************************************************************************
 * Copyright (c) 2007, 2017 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Florian Ingerl <imelflorianingerl@gmail.com> - Bug 109481 - [find/replace] replace doesn't work when using a regex with a lookahead or boundary matchers
 *******************************************************************************/
package org.eclipse.search.internal.ui.text;

import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import com.ibm.icu.text.Collator;

import org.eclipse.core.filesystem.URIUtil;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;

import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEditGroup;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextUtilities;

import org.eclipse.search.internal.core.text.PatternConstructor;
import org.eclipse.search.internal.ui.Messages;
import org.eclipse.search.internal.ui.SearchMessages;
import org.eclipse.search.ui.text.Match;

import org.eclipse.search2.internal.ui.InternalSearchUI;
import org.eclipse.search2.internal.ui.text.PositionTracker;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.TextEditChangeGroup;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;


public class ReplaceRefactoring extends Refactoring {

	private static class MatchGroup {
		public TextEditChangeGroup group;
		public FileMatch match;

		public MatchGroup(TextEditChangeGroup group, FileMatch match) {
			this.group= group;
			this.match= match;
		}
	}

	public static class SearchResultUpdateChange extends Change {

		private MatchGroup[] fMatchGroups;
		private Match[] fMatches;

		private Map<URI, ArrayList<FileMatch>> fIgnoredMatches;
		private final FileSearchResult fResult;
		private final boolean fIsRemove;

		public SearchResultUpdateChange(FileSearchResult result, MatchGroup[] matchGroups, Map<URI, ArrayList<FileMatch>> ignoredMatches) {
			this(result, null, ignoredMatches, true);
			fMatchGroups= matchGroups;
		}

		private SearchResultUpdateChange(FileSearchResult result, Match[] matches, Map<URI, ArrayList<FileMatch>> ignoredMatches, boolean isRemove) {
			fResult= result;
			fMatches= matches;
			fIgnoredMatches= ignoredMatches;
			fIsRemove= isRemove;
		}

		@Override
		public Object getModifiedElement() {
			return null;
		}

		@Override
		public String getName() {
			return SearchMessages.ReplaceRefactoring_result_update_name;
		}

		@Override
		public void initializeValidationData(IProgressMonitor pm) {
		}

		@Override
		public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException {
			return new RefactoringStatus();
		}

		private Match[] getMatches() {
			if (fMatches == null) {
				ArrayList<FileMatch> matches= new ArrayList<>();
				for (MatchGroup curr : fMatchGroups) {
					if (curr.group.isEnabled()) {
						FileMatch match= curr.match;
						matches.add(match);

						if (fIgnoredMatches == null)
							continue;

						// Add matches that we removed before starting the refactoring
						IFile file= match.getFile();
						URI uri= file.getLocationURI();
						if (uri != null) {
							ArrayList<FileMatch> ignoredMatches= fIgnoredMatches.get(uri);
							if (ignoredMatches != null)
								matches.addAll(ignoredMatches);
						}
					}
				}
				fMatches= matches.toArray(new Match[matches.size()]);
				fMatchGroups= null;
			}
			return fMatches;
		}

		@Override
		public Change perform(IProgressMonitor pm) throws CoreException {
			Match[] matches= getMatches();
			if (fIsRemove) {
				fResult.removeMatches(matches);
			} else {
				fResult.addMatches(matches);
			}
			return new SearchResultUpdateChange(fResult, matches, fIgnoredMatches, !fIsRemove);
		}

	}



	private final FileSearchResult fResult;
	private final Object[] fSelection;

	private final HashMap<IFile, Set<FileMatch>> fMatches;

	/** Map that keeps already collected locations. */
	private final Map<URI, IFile> fAlreadyCollected;

	/** Map that keeps ignored matches (can be null). */
	private Map<URI, ArrayList<FileMatch>> fIgnoredMatches;

	private String fReplaceString;

	private Change fChange;

	public ReplaceRefactoring(FileSearchResult result, Object[] selection) {
		Assert.isNotNull(result);

		fResult= result;
		fSelection= selection;

		fMatches= new HashMap<>();
		fAlreadyCollected= new HashMap<>(selection != null ? selection.length : result.getElements().length);

		fReplaceString= null;
	}

	@Override
	public String getName() {
		return SearchMessages.ReplaceRefactoring_refactoring_name;
	}

	public void setReplaceString(String string) {
		fReplaceString= string;
	}

	@Override
	public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		String searchString= getQuery().getSearchString();
		if (searchString.length() == 0) {
			return RefactoringStatus.createFatalErrorStatus(SearchMessages.ReplaceRefactoring_error_illegal_search_string);
		}
		fMatches.clear();

		if (fSelection != null) {
			for (Object element : fSelection) {
				collectMatches(element);
			}
		} else {
			Object[] elements= fResult.getElements();
			for (Object element : elements) {
				collectMatches(element);
			}
		}
		if (!hasMatches()) {
			return RefactoringStatus.createFatalErrorStatus(SearchMessages.ReplaceRefactoring_error_no_matches);
		}
		return new RefactoringStatus();
	}

	private void collectMatches(Object object) throws CoreException {
		if (object instanceof LineElement) {
			LineElement lineElement= (LineElement) object;
			FileMatch[] matches= lineElement.getMatches(fResult);
			for (FileMatch fileMatch : matches) {
				if (isMatchToBeIncluded(fileMatch)) {
					getBucket(fileMatch.getFile()).add(fileMatch);
				}
			}
		} else if (object instanceof IContainer) {
			IContainer container= (IContainer) object;
			IResource[] members= container.members();
			for (IResource member : members) {
				collectMatches(member);
			}
		} else if (object instanceof IFile) {
			Match[] matches= fResult.getMatches(object);
			if (matches.length > 0) {
				Collection<FileMatch> bucket= null;
				for (Match match : matches) {
					FileMatch fileMatch= (FileMatch) match;
					if (isMatchToBeIncluded(fileMatch)) {
						if (bucket == null) {
							bucket= getBucket((IFile)object);
						}
						bucket.add(fileMatch);
					}
				}
			}
		}
	}

	public int getNumberOfFiles() {
		return fMatches.keySet().size();
	}

	public int getNumberOfMatches() {
		int count= 0;
		for (Set<FileMatch> bucket : fMatches.values()) {
			count += bucket.size();
		}
		return count;
	}

	public boolean hasMatches() {
		return !fMatches.isEmpty();
	}

	/**
	 * Checks whether the match should be included. Also collects ignored matches whose
	 * file is linked to an already collected match.
	 *
	 * @param match the match
	 * @return <code>true</code> iff the match should be included
	 * @since 3.7
	 */
	private boolean isMatchToBeIncluded(FileMatch match) {
		IFile file= match.getFile();
		URI uri= file.getLocationURI();
		if (uri == null)
			return true;

		for (URI uri2 : fAlreadyCollected.keySet()) {
			if (URIUtil.equals(uri2, uri)) {
				if (file.equals(fAlreadyCollected.get(uri)))
					return true; // another FileMatch for an IFile which already had matches

				if (fIgnoredMatches == null)
					fIgnoredMatches= new HashMap<>();

				ArrayList<FileMatch> matches= fIgnoredMatches.get(uri);
				if (matches == null) {
					matches= new ArrayList<>();
					fIgnoredMatches.put(uri, matches);
				}
				matches.add(match);

				return false;
			}
		}

		fAlreadyCollected.put(uri, file);
		return true;
	}

	private Set<FileMatch> getBucket(IFile file) {
		Set<FileMatch> set= fMatches.get(file);
		if (set == null) {
			set= new HashSet<>();
			fMatches.put(file, set);
		}
		return set;
	}

	@Override
	public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		if (fReplaceString == null) {
			return RefactoringStatus.createFatalErrorStatus(SearchMessages.ReplaceRefactoring_error_no_replace_string);
		}

		Pattern pattern= null;
		FileSearchQuery query= getQuery();
		if (query.isRegexSearch()) {
			pattern= createSearchPattern(query);
		}

		RefactoringStatus resultingStatus= new RefactoringStatus();

		Collection<IFile> allFilesSet= fMatches.keySet();
		IFile[] allFiles= allFilesSet.toArray(new IFile[allFilesSet.size()]);
		Arrays.sort(allFiles, new Comparator<IFile>() {
			private Collator fCollator= Collator.getInstance();
			@Override
			public int compare(IFile o1, IFile o2) {
				String p1= o1.getFullPath().toString();
				String p2= o2.getFullPath().toString();
				return fCollator.compare(p1, p2);
			}
		});
		checkFilesToBeChanged(allFiles, resultingStatus);
		if (resultingStatus.hasFatalError()) {
			return resultingStatus;
		}

		CompositeChange compositeChange= new CompositeChange(SearchMessages.ReplaceRefactoring_composite_change_name);
		compositeChange.markAsSynthetic();

		ArrayList<MatchGroup> matchGroups= new ArrayList<>();
		boolean hasChanges= false;
		try {
			for (IFile file : allFiles) {
				Set<FileMatch> bucket= fMatches.get(file);
				if (!bucket.isEmpty()) {
					try {
						TextChange change= createFileChange(file, pattern, bucket, resultingStatus, matchGroups);
						if (change != null) {
							compositeChange.add(change);
							hasChanges= true;
						}
					} catch (CoreException e) {
						String message= Messages.format(SearchMessages.ReplaceRefactoring_error_access_file, new Object[] { file.getName(), e.getLocalizedMessage() });
						return RefactoringStatus.createFatalErrorStatus(message);
					}
				}
			}
		} catch (PatternSyntaxException e) {
			String message= Messages.format(SearchMessages.ReplaceRefactoring_error_replacement_expression, e.getLocalizedMessage());
			return RefactoringStatus.createFatalErrorStatus(message);
		}
		if (!hasChanges && resultingStatus.isOK()) {
			return RefactoringStatus.createFatalErrorStatus(SearchMessages.ReplaceRefactoring_error_no_changes);
		}

		compositeChange.add(new SearchResultUpdateChange(fResult, matchGroups.toArray(new MatchGroup[matchGroups.size()]), fIgnoredMatches));

		fChange= compositeChange;
		return resultingStatus;
	}

	private void checkFilesToBeChanged(IFile[] filesToBeChanged, RefactoringStatus resultingStatus) throws CoreException {
		ArrayList<IFile> readOnly= new ArrayList<>();
		for (IFile file : filesToBeChanged) {
			if (file.isReadOnly())
				readOnly.add(file);
		}
		IFile[] readOnlyFiles= readOnly.toArray(new IFile[readOnly.size()]);

		IStatus status= ResourcesPlugin.getWorkspace().validateEdit(readOnlyFiles, getValidationContext());
		if (status.getSeverity() == IStatus.CANCEL) {
			throw new OperationCanceledException();
		}
		resultingStatus.merge(RefactoringStatus.create(status));
		if (resultingStatus.hasFatalError()) {
			return;
		}
		resultingStatus.merge(ResourceChangeChecker.checkFilesToBeChanged(filesToBeChanged, null));
	}

	private TextChange createFileChange(IFile file, Pattern pattern, Set<FileMatch> matches, RefactoringStatus resultingStatus, Collection<MatchGroup> matchGroups) throws PatternSyntaxException, CoreException {
		PositionTracker tracker= InternalSearchUI.getInstance().getPositionTracker();

		TextFileChange change= new TextFileChange(Messages.format(SearchMessages.ReplaceRefactoring_group_label_change_for_file, file.getName()), file);
		change.setEdit(new MultiTextEdit());

		ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
		manager.connect(file.getFullPath(), LocationKind.IFILE, null);
		try {
			ITextFileBuffer textFileBuffer= manager.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
			if (textFileBuffer == null) {
				resultingStatus.addError(Messages.format(SearchMessages.ReplaceRefactoring_error_accessing_file_buffer, file.getName()));
				return null;
			}
			IDocument document= textFileBuffer.getDocument();
			String lineDelimiter= TextUtilities.getDefaultLineDelimiter(document);

			for (FileMatch match : matches) {
				int offset= match.getOffset();
				int length= match.getLength();
				Position currentPosition= tracker.getCurrentPosition(match);
				if (currentPosition != null) {
					offset= currentPosition.offset;
					if (length != currentPosition.length) {
						resultingStatus.addError(Messages.format(SearchMessages.ReplaceRefactoring_error_match_content_changed, file.getName()));
						continue;
					}
				}

				String originalText= getOriginalText(document, offset, length);
				if (originalText == null) {
					resultingStatus.addError(Messages.format(SearchMessages.ReplaceRefactoring_error_match_content_changed, file.getName()));
					continue;
				}

				String replacementString= PatternConstructor.interpretReplaceEscapes(fReplaceString, originalText,
						lineDelimiter);
				replacementString= computeReplacementString(pattern, document, offset, replacementString);
				if (replacementString == null) {
					resultingStatus.addError(Messages.format(SearchMessages.ReplaceRefactoring_error_match_content_changed, file.getName()));
					continue;
				}

				ReplaceEdit replaceEdit= new ReplaceEdit(offset, length, replacementString);
				change.addEdit(replaceEdit);
				TextEditChangeGroup textEditChangeGroup= new TextEditChangeGroup(change, new TextEditGroup(SearchMessages.ReplaceRefactoring_group_label_match_replace, replaceEdit));
				change.addTextEditChangeGroup(textEditChangeGroup);
				matchGroups.add(new MatchGroup(textEditChangeGroup, match));
			}
		} finally {
			manager.disconnect(file.getFullPath(), LocationKind.IFILE, null);
		}
		return change;
	}

	private static String getOriginalText(IDocument doc, int offset, int length) {
		try {
			return doc.get(offset, length);
		} catch (BadLocationException e) {
			return null;
		}
	}

	private Pattern createSearchPattern(FileSearchQuery query) {
		return PatternConstructor.createPattern(query.getSearchString(), true, true, query.isCaseSensitive(), false);
	}

	private String computeReplacementString(Pattern pattern, IDocument document, int offset, String replacementText)
			throws PatternSyntaxException {
		if (pattern != null) {
			try {
				Matcher matcher= pattern.matcher(document.get());
				if (matcher.find(offset)) {
					StringBuffer sb= new StringBuffer();
		        	matcher.appendReplacement(sb, replacementText);
					return sb.substring(offset);
		        } else {
		        	return null;
		        }
			} catch (IndexOutOfBoundsException ex) {
				throw new PatternSyntaxException(ex.getLocalizedMessage(), replacementText, -1);
			}
		}
		return replacementText;
	}

	public FileSearchQuery getQuery() {
		return (FileSearchQuery) fResult.getQuery();
	}


	@Override
	public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		return fChange;
	}

}
