/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Martin Burger <m@rtin-burger.de> patch for #93810 and #93901
 *******************************************************************************/
package org.eclipse.compare.internal.patch;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.compare.internal.core.Messages;
import org.eclipse.compare.internal.core.patch.DiffProject;
import org.eclipse.compare.internal.core.patch.FileDiffResult;
import org.eclipse.compare.internal.core.patch.FilePatch2;
import org.eclipse.compare.internal.core.patch.Hunk;
import org.eclipse.compare.internal.core.patch.PatchReader;
import org.eclipse.compare.patch.IHunk;
import org.eclipse.compare.patch.IHunkFilter;
import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.text.TextUtilities;

/**
 * A Patcher
 * - knows how to parse various patch file formats into some in-memory structure,
 * - holds onto the parsed data and the options to use when applying the patches,
 * - knows how to apply the patches to files and folders.
 */
public class Patcher implements IHunkFilter {

	static protected final String REJECT_FILE_EXTENSION= ".rej"; //$NON-NLS-1$

	static protected final String MARKER_TYPE= "org.eclipse.compare.rejectedPatchMarker"; //$NON-NLS-1$

	/**
	 * Property used to associate a patcher with a {@link PatchConfiguration}
	 */
	public static final String PROP_PATCHER = "org.eclipse.compare.patcher"; //$NON-NLS-1$

	public interface IFileValidator {
		boolean validateResources(IFile[] array);
	}

	// diff formats
	//	private static final int CONTEXT= 0;
	//	private static final int ED= 1;
	//	private static final int NORMAL= 2;
	//	private static final int UNIFIED= 3;

	private FilePatch2[] fDiffs;
	private IResource fTarget;
	// patch options
	private Set<Object> disabledElements = new HashSet<>();
	private Map<FilePatch2, FileDiffResult> diffResults = new HashMap<>();
	private final Map<FilePatch2, byte[]> contentCache = new HashMap<>();
	private Set<Hunk> mergedHunks = new HashSet<>();

	private final PatchConfiguration configuration;
	private boolean fGenerateRejectFile = false;

	public Patcher() {
		configuration = new PatchConfiguration();
		configuration.setProperty(PROP_PATCHER, this);
		configuration.addHunkFilter(this);
	}

	/*
	 * Returns an array of Diffs after a successful call to <code>parse</code>.
	 * If <code>parse</code> hasn't been called returns <code>null</code>.
	 */
	public FilePatch2[] getDiffs() {
		if (fDiffs == null)
			return new FilePatch2[0];
		return fDiffs;
	}

	public IPath getPath(FilePatch2 diff) {
		return diff.getStrippedPath(getStripPrefixSegments(), isReversed());
	}

	/*
	 * Returns <code>true</code> if new value differs from old.
	 */
	public boolean setStripPrefixSegments(int strip) {
		if (strip != getConfiguration().getPrefixSegmentStripCount()) {
			getConfiguration().setPrefixSegmentStripCount(strip);
			return true;
		}
		return false;
	}

	int getStripPrefixSegments() {
		return getConfiguration().getPrefixSegmentStripCount();
	}

	/*
	 * Returns <code>true</code> if new value differs from old.
	 */
	public boolean setFuzz(int fuzz) {
		if (fuzz != getConfiguration().getFuzz()) {
			getConfiguration().setFuzz(fuzz);
			return true;
		}
		return false;
	}

	public int getFuzz(){
		return getConfiguration().getFuzz();
	}

	/*
	 * Returns <code>true</code> if new value differs from old.
	 */
	public boolean setIgnoreWhitespace(boolean ignoreWhitespace) {
		if (ignoreWhitespace != getConfiguration().isIgnoreWhitespace()) {
			getConfiguration().setIgnoreWhitespace(ignoreWhitespace);
			return true;
		}
		return false;
	}

	public boolean isIgnoreWhitespace() {
		return getConfiguration().isIgnoreWhitespace();
	}

	public boolean isGenerateRejectFile() {
		return fGenerateRejectFile;
	}

	public void setGenerateRejectFile(boolean generateRejectFile) {
		fGenerateRejectFile = generateRejectFile;
	}

	//---- parsing patch files

	public void parse(IStorage storage) throws IOException, CoreException {
		BufferedReader reader = Utilities.createReader(storage);
		try {
			parse(reader);
		} finally {
			try {
				reader.close();
			} catch (IOException e) { //ignored
			}
		}
	}

	public void parse(BufferedReader reader) throws IOException {
		PatchReader patchReader = new PatchReader() {
			@Override
			protected FilePatch2 createFileDiff(IPath oldPath, long oldDate,
					IPath newPath, long newDate) {
				return new FilePatch(oldPath, oldDate, newPath, newDate);
			}
		};
		patchReader.parse(reader);
		patchParsed(patchReader);
	}

	protected void patchParsed(PatchReader patchReader) {
		fDiffs = patchReader.getDiffs();
	}

	public void countLines() {
		FilePatch2[] fileDiffs = getDiffs();
		for (FilePatch2 fileDiff : fileDiffs) {
			int addedLines = 0;
			int removedLines = 0;
			for (int j = 0; j < fileDiff.getHunkCount(); j++) {
				IHunk hunk = fileDiff.getHunks()[j];
				String[] lines = ((Hunk) hunk).getLines();
				for (String line : lines) {
					char c = line.charAt(0);
					switch (c) {
					case '+':
						addedLines++;
						continue;
					case '-':
						removedLines++;
						continue;
					}
				}
			}
			fileDiff.setAddedLines(addedLines);
			fileDiff.setRemovedLines(removedLines);
		}
	}

	//---- applying a patch file

	public void applyAll(IProgressMonitor pm, IFileValidator validator) throws CoreException {

		int i;

		IFile singleFile= null;	// file to be patched
		IContainer container= null;
		if (fTarget instanceof IContainer)
			container= (IContainer) fTarget;
		else if (fTarget instanceof IFile) {
			singleFile= (IFile) fTarget;
			container= singleFile.getParent();
		} else {
			Assert.isTrue(false);
		}

		// get all files to be modified in order to call validateEdit
		List<IFile> list= new ArrayList<>();
		if (singleFile != null)
			list.add(singleFile);
		else {
			for (i= 0; i < fDiffs.length; i++) {
				FilePatch2 diff= fDiffs[i];
				if (isEnabled(diff)) {
					switch (diff.getDiffType(isReversed())) {
					case FilePatch2.CHANGE:
						list.add(createPath(container, getPath(diff)));
						break;
					}
				}
			}
		}
		if (! validator.validateResources(list.toArray(new IFile[list.size()]))) {
			return;
		}

		final int WORK_UNIT= 10;
		if (pm != null) {
			String message= Messages.Patcher_0;
			pm.beginTask(message, fDiffs.length*WORK_UNIT);
		}

		for (i= 0; i < fDiffs.length; i++) {

			int workTicks= WORK_UNIT;

			FilePatch2 diff= fDiffs[i];
			if (isEnabled(diff)) {

				IPath path= getPath(diff);
				if (pm != null)
					pm.subTask(path.toString());

				IFile file= singleFile != null
								? singleFile
								: createPath(container, path);

				List<Hunk> failed= new ArrayList<>();

				int type= diff.getDiffType(isReversed());
				switch (type) {
				case FilePatch2.ADDITION:
					// patch it and collect rejected hunks
					List<String> result= apply(diff, file, true, failed);
					if (result != null)
						store(LineReader.createString(isPreserveLineDelimeters(), result), file, SubMonitor.convert(pm, workTicks));
					workTicks-= WORK_UNIT;
					break;
				case FilePatch2.DELETION:
					file.delete(true, true, SubMonitor.convert(pm, workTicks));
					workTicks-= WORK_UNIT;
					break;
				case FilePatch2.CHANGE:
					// patch it and collect rejected hunks
					result= apply(diff, file, false, failed);
					if (result != null)
						store(LineReader.createString(isPreserveLineDelimeters(), result), file, SubMonitor.convert(pm, workTicks));
					workTicks-= WORK_UNIT;
					break;
				}

				if (isGenerateRejectFile() && failed.size() > 0) {
					IPath pp = getRejectFilePath(path);
					file= createPath(container, pp);
					if (file != null) {
						store(getRejected(failed), file, pm);
						try {
							IMarker marker= file.createMarker(MARKER_TYPE);
							marker.setAttribute(IMarker.MESSAGE, Messages.Patcher_1);
							marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
						} catch (CoreException ex) {
							// NeedWork
						}
					}
				}
			}

			if (pm != null) {
				if (pm.isCanceled())
					break;
				if (workTicks > 0)
					pm.worked(workTicks);
			}
		}
	}

	private IPath getRejectFilePath(IPath path) {
		IPath pp= null;
		if (path.segmentCount() > 1) {
			pp= path.removeLastSegments(1);
			pp= pp.append(path.lastSegment() + REJECT_FILE_EXTENSION);
		} else
			pp= new Path(path.lastSegment() + REJECT_FILE_EXTENSION);
		return pp;
	}

	List<String> apply(FilePatch2 diff, IFile file, boolean create, List<Hunk> failedHunks) {
		FileDiffResult result = getDiffResult(diff);
		List<String> lines = LineReader.load(file, create);
		result.patch(lines, null);
		failedHunks.addAll(result.getFailedHunks());
		if (hasCachedContents(diff)) {
			// Used the cached contents since they would have been provided by the user
			return getCachedLines(diff);
		} else if (!result.hasMatches()) {
			// Return null if there were no matches
			return null;
		}
		return result.getLines();
	}

	/*
	 * Converts the string into bytes and stores them in the given file.
	 */
	protected void store(String contents, IFile file, IProgressMonitor pm) throws CoreException {

		if (!file.exists()) {
			if (FileBuffers.getTextFileBufferManager().isTextFileLocation(file.getFullPath(), true)) {
				// For new text files use the line delimiter as defined in the workspace
				String expectedLD= getLineDelimiterPreference(file);
				if (expectedLD != null) {
					String patchLD= TextUtilities.determineLineDelimiter(contents, expectedLD);
					if (!expectedLD.equals(patchLD))
						contents= contents.replaceAll(patchLD, expectedLD);
				}
			}
		}

		byte[] bytes;
		try {
			bytes= contents.getBytes(Utilities.getCharset(file));
		} catch (UnsupportedEncodingException x) {
			// uses default encoding
			bytes= contents.getBytes();
		}

		store(bytes,file, pm);
	}

	private static String getLineDelimiterPreference(IFile file) {
		IScopeContext[] scopeContext;
		if (file != null && file.getProject() != null) {
			// project preference
			scopeContext= new IScopeContext[] { new ProjectScope(file.getProject()) };
			String lineDelimiter= Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, scopeContext);
			if (lineDelimiter != null)
				return lineDelimiter;
		}
		// workspace preference
		scopeContext= new IScopeContext[] { InstanceScope.INSTANCE };
		return Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, scopeContext);
	}

	protected void store(byte[] bytes, IFile file, IProgressMonitor pm) throws CoreException {
		InputStream is= new ByteArrayInputStream(bytes);
		try {
			if (file.exists()) {
				file.setContents(is, false, true, pm);
			} else {
				file.create(is, false, pm);
			}
		} finally {
			if (is != null)
				try {
					is.close();
				} catch(IOException ex) {
					// silently ignored
				}
		}
	}

	public boolean isPreserveLineDelimeters() {
		return true;
	}

	public static String getRejected(List<Hunk> failedHunks) {
		if (failedHunks.size() <= 0)
			return null;

		String lineSeparator= System.getProperty("line.separator"); //$NON-NLS-1$
		StringBuilder sb= new StringBuilder();
		Iterator<Hunk> iter= failedHunks.iterator();
		while (iter.hasNext()) {
			Hunk hunk= iter.next();
			sb.append(hunk.getRejectedDescription());
			sb.append(lineSeparator);
			sb.append(hunk.getContent());
		}
		return sb.toString();
	}

	/*
	 * Ensures that a file with the given path exists in
	 * the given container. Folder are created as necessary.
	 */
	protected IFile createPath(IContainer container, IPath path) throws CoreException {
		if (path.segmentCount() > 1) {
			IContainer childContainer;
			if (container instanceof IWorkspaceRoot) {
				IProject project = ((IWorkspaceRoot)container).getProject(path.segment(0));
				if (!project.exists())
					project.create(null);
				if (!project.isOpen())
					project.open(null);
				childContainer = project;
			} else {
				IFolder f= container.getFolder(path.uptoSegment(1));
				if (!f.exists())
					f.create(false, true, null);
				childContainer = f;
			}
			return createPath(childContainer, path.removeFirstSegments(1));
		}
		// a leaf
		return container.getFile(path);
	}

	public IResource getTarget() {
		return fTarget;
	}

	public void setTarget(IResource target) {
		fTarget= target;
	}


	public IFile getTargetFile(FilePatch2 diff) {
		IPath path = diff.getStrippedPath(getStripPrefixSegments(), isReversed());
		return existsInTarget(path);
	}

	/**
	 * Iterates through all of the resources contained in the Patch Wizard target
	 * and looks to for a match to the passed in file
	 * @param path
	 * @return IFile which matches the passed in path or null if none found
	 */
	public IFile existsInTarget(IPath path) {
		if (fTarget instanceof IFile) { // special case
			IFile file= (IFile) fTarget;
			if (matches(file.getFullPath(), path))
				return file;
		} else if (fTarget instanceof IContainer) {
			IContainer c= (IContainer) fTarget;
			if (c.exists(path))
				return c.getFile(path);
		}
		return null;
	}

	/**
	 * Returns true if path completely matches the end of fullpath
	 * @param fullpath
	 * @param path
	 * @return true if path matches, false otherwise
	 */
	private boolean matches(IPath fullpath, IPath path) {
		for (IPath p= fullpath; path.segmentCount()<=p.segmentCount(); p= p.removeFirstSegments(1)) {
			if (p.equals(path))
				return true;
		}
		return false;
	}

	public int calculatePrefixSegmentCount() {
		//Update prefix count - go through all of the diffs and find the smallest
		//path segment contained in all diffs.
		int length= 99;
		if (fDiffs!=null) {
			for (FilePatch2 diff : fDiffs) {
				length= Math.min(length, diff.segmentCount());
			}
			if (ResourcesPlugin.getWorkspace().getRoot().equals(fTarget))
				length--;
		}
		return length;
	}

	public void addDiff(FilePatch2 newDiff){
		FilePatch2[] temp = new FilePatch2[fDiffs.length + 1];
		System.arraycopy(fDiffs,0, temp, 0, fDiffs.length);
		temp[fDiffs.length] = newDiff;
		fDiffs = temp;
	}

	public void removeDiff(FilePatch2 diffToRemove){
		FilePatch2[] temp = new FilePatch2[fDiffs.length - 1];
		int counter = 0;
		for (FilePatch2 diff : fDiffs) {
			if (diff != diffToRemove) {
				temp[counter++] = diff;
			}
		}
		fDiffs = temp;
	}

	public void setEnabled(Object element, boolean enabled) {
		if (element instanceof DiffProject)
			setEnabledProject((DiffProject) element, enabled);
		if (element instanceof FilePatch2)
			setEnabledFile((FilePatch2)element, enabled);
		if (element instanceof Hunk)
			setEnabledHunk((Hunk) element, enabled);
	}

	private void setEnabledProject(DiffProject projectDiff, boolean enabled) {
		FilePatch2[] diffFiles = projectDiff.getFileDiffs();
		for (FilePatch2 diffFile : diffFiles) {
			setEnabledFile(diffFile, enabled);
		}
	}

	private void setEnabledFile(FilePatch2 fileDiff, boolean enabled) {
		IHunk[] hunks = fileDiff.getHunks();
		for (IHunk hunk : hunks) {
			setEnabledHunk((Hunk) hunk, enabled);
		}
	}

	private void setEnabledHunk(Hunk hunk, boolean enabled) {
		if (enabled) {
			disabledElements.remove(hunk);
			FilePatch2 file = hunk.getParent();
			disabledElements.remove(file);
			DiffProject project = file.getProject();
			if (project != null)
				disabledElements.remove(project);
		} else {
			disabledElements.add(hunk);
			FilePatch2 file = hunk.getParent();
			if (disabledElements.containsAll(Arrays.asList(file.getHunks()))) {
				disabledElements.add(file);
				DiffProject project = file.getProject();
				if (project != null
						&& disabledElements.containsAll(Arrays.asList(project
								.getFileDiffs())))
					disabledElements.add(project);
			}
		}
	}

	public boolean isEnabled(Object element) {
		if (disabledElements.contains(element))
			return false;
		Object parent = getElementParent(element);
		if (parent == null)
			return true;
		return isEnabled(parent);
	}

	protected Object getElementParent(Object element) {
		if (element instanceof Hunk) {
			Hunk hunk = (Hunk) element;
			return hunk.getParent();
		}
		return null;
	}

	/**
	 * Calculate the fuzz factor that will allow the most hunks to be matched.
	 * @param monitor a progress monitor
	 * @return the fuzz factor or <code>-1</code> if no hunks could be matched
	 */
	public int guessFuzzFactor(IProgressMonitor monitor) {
		try {
			monitor.beginTask(Messages.Patcher_2, IProgressMonitor.UNKNOWN);
			FilePatch2[] diffs= getDiffs();
			if (diffs==null||diffs.length<=0)
				return -1;
			int fuzz= -1;
			for (FilePatch2 d : diffs) {
				IFile file= getTargetFile(d);
				if (file != null && file.exists()) {
					List<String> lines= LineReader.load(file, false);
					FileDiffResult result = getDiffResult(d);
					int f = result.calculateFuzz(lines, monitor);
					if (f > fuzz)
						fuzz = f;
				}
			}
			return fuzz;
		} finally {
			monitor.done();
		}
	}

	public void refresh() {
		diffResults.clear();
		refresh(getDiffs());
	}

	public void refresh(FilePatch2[] diffs) {
		for (FilePatch2 diff : diffs) {
			FileDiffResult result = getDiffResult(diff);
			((WorkspaceFileDiffResult)result).refresh();
		}
	}

	public FileDiffResult getDiffResult(FilePatch2 diff) {
		FileDiffResult result = diffResults.get(diff);
		if (result == null) {
			result = new WorkspaceFileDiffResult(diff, getConfiguration());
			diffResults.put(diff, result);
		}
		return result;
	}

	public PatchConfiguration getConfiguration() {
		return configuration;
	}

	/**
	 * Return the project that contains this diff or <code>null</code>
	 * if the patch is not a workspace patch.
	 * @param diff the diff
	 * @return the project that contains the diff
	 */
	public DiffProject getProject(FilePatch2 diff) {
		return diff.getProject();
	}

	/*
	 * Returns <code>true</code> if new value differs from old.
	 */
	public boolean setReversed(boolean reverse) {
		if (getConfiguration().isReversed() != reverse) {
			getConfiguration().setReversed(reverse);
			refresh();
			return true;
		}
		return false;
	}

	public boolean isReversed() {
		return getConfiguration().isReversed();
	}

	/**
	 * Cache the contents for the given file diff. These contents
	 * will be used for the diff when the patch is applied. When the
	 * patch is applied, it is assumed that the provided contents
	 * already have all relevant hunks applied.
	 * @param diff the file diff
	 * @param contents the contents for the file diff
	 */
	public void cacheContents(FilePatch2 diff, byte[] contents) {
		contentCache.put(diff, contents);
	}

	/**
	 * Return whether contents have been cached for the
	 * given file diff.
	 * @param diff the file diff
	 * @return whether contents have been cached for the file diff
	 * @see #cacheContents(FilePatch2, byte[])
	 */
	public boolean hasCachedContents(FilePatch2 diff) {
		return contentCache.containsKey(diff);
	}

	/**
	 * Return the content lines that are cached for the given
	 * file diff.
	 * @param diff the file diff
	 * @return the content lines that are cached for the file diff
	 */
	public List<String> getCachedLines(FilePatch2 diff) {
		byte[] contents = contentCache.get(diff);
		if (contents != null) {
			BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(contents)));
			return LineReader.readLines(reader);
		}
		return null;
	}

	/**
	 * Return the contents that are cached for the given diff or
	 * <code>null</code> if there is no contents cached.
	 * @param diff the diff
	 * @return the contents that are cached for the given diff or
	 * <code>null</code>
	 */
	public byte[] getCachedContents(FilePatch2 diff) {
		return contentCache.get(diff);
	}

	/**
	 * Return whether the patcher has any cached contents.
	 * @return whether the patcher has any cached contents
	 */
	public boolean hasCachedContents() {
		return !contentCache.isEmpty();
	}

	/**
	 * Clear any cached contents.
	 */
	public void clearCachedContents() {
		contentCache.clear();
		mergedHunks.clear();
	}

	public void setProperty(String key, Object value) {
		getConfiguration().setProperty(key, value);
	}

	public Object getProperty(String key) {
		return getConfiguration().getProperty(key);
	}

	public boolean isManuallyMerged(Hunk hunk) {
		return mergedHunks.contains(hunk);
	}

	public void setManuallyMerged(Hunk hunk, boolean merged) {
		if (merged)
			mergedHunks.add(hunk);
		else
			mergedHunks.remove(hunk);
	}

	public IProject getTargetProject(FilePatch2 diff) {
		DiffProject dp = getProject(diff);
		if (dp != null)
			return Utilities.getProject(dp);
		IResource tr = getTarget();
		if (tr instanceof IWorkspaceRoot) {
			IWorkspaceRoot root = (IWorkspaceRoot) tr;
			return root.getProject(diff.getPath(isReversed()).segment(0));
		}
		return tr.getProject();
	}

	public static Patcher getPatcher(PatchConfiguration configuration) {
		return (Patcher)configuration.getProperty(PROP_PATCHER);
	}

	public boolean hasRejects() {
		for (Iterator<FileDiffResult> iterator = diffResults.values().iterator(); iterator.hasNext();) {
			FileDiffResult result = iterator.next();
			if (result.hasRejects())
				return true;
		}
		return false;
	}

	@Override
	public boolean select(IHunk hunk) {
		return isEnabled(hunk);
	}
}
