/*******************************************************************************
 * Copyright (c) 2000, 2011 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
 *******************************************************************************/
package org.eclipse.compare.internal.core.patch;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.compare.patch.IFilePatchResult;
import org.eclipse.compare.patch.IHunk;
import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.core.runtime.Assert;

/**
 * A Hunk describes a range of changed lines and some context lines.
 */
public class Hunk implements IHunk {
	private FilePatch2 fParent;
	private int fOldStart, fOldLength;
	private int fNewStart, fNewLength;
	private String[] fLines;
	private int hunkType;
	private String charset = null;

	public static Hunk createHunk(FilePatch2 parent, int[] oldRange, int[] newRange,
			List<String> lines, boolean hasLineAdditions, boolean hasLineDeletions, boolean hasContextLines) {
		int oldStart = 0;
		int oldLength = 0;
		int newStart = 0;
		int newLength = 0;
		if (oldRange[0] > 0)
			oldStart= oldRange[0]-1;	// line number start at 0!
		else
			oldStart= 0;
		oldLength= oldRange[1];
		if (newRange[0] > 0)
			newStart= newRange[0]-1;	// line number start at 0!
		else
			newStart= 0;
		newLength= newRange[1];
		int hunkType = FilePatch2.CHANGE;
		if (!hasContextLines) {
			if (hasLineAdditions && !hasLineDeletions) {
				hunkType = FilePatch2.ADDITION;
			} else if (!hasLineAdditions && hasLineDeletions) {
				hunkType = FilePatch2.DELETION;
			}
		}
		return new Hunk(parent, hunkType, oldStart, oldLength, newStart, newLength, lines.toArray(new String[lines.size()]));
	}

	public Hunk(FilePatch2 parent, int hunkType, int oldStart, int oldLength,
			int newStart, int newLength, String[] lines) {
		this.fParent = parent;
        if (this.fParent != null) {
            this.fParent.add(this);
        }
		this.hunkType = hunkType;
		this.fOldLength = oldLength;
		this.fOldStart = oldStart;
		this.fNewLength = newLength;
		this.fNewStart = newStart;
		this.fLines = lines;
	}

    public Hunk(FilePatch2 parent, Hunk toCopy) {
    	this(parent, toCopy.hunkType, toCopy.fOldStart, toCopy.fOldLength, toCopy.fNewStart, toCopy.fNewLength, toCopy.fLines);
    }

	/*
	 * Returns the contents of this hunk.
	 * Each line starts with a control character. Their meaning is as follows:
	 * <ul>
	 * <li>
	 * '+': add the line
	 * <li>
	 * '-': delete the line
	 * <li>
	 * ' ': no change, context line
	 * </ul>
	 */
	public String getContent() {
		StringBuilder sb= new StringBuilder();
		for (int i= 0; i < this.fLines.length; i++) {
			String line= this.fLines[i];
			sb.append(line.substring(0, LineReader.length(line)));
			sb.append('\n');
		}
		return sb.toString();
	}

	/*
	 * Returns a descriptive String for this hunk.
	 * It is in the form old_start,old_length -> new_start,new_length.
	 */
	String getDescription() {
		StringBuilder sb= new StringBuilder();
		sb.append(Integer.toString(this.fOldStart));
		sb.append(',');
		sb.append(Integer.toString(this.fOldLength));
		sb.append(" -> "); //$NON-NLS-1$
		sb.append(Integer.toString(this.fNewStart));
		sb.append(',');
		sb.append(Integer.toString(this.fNewLength));
		return sb.toString();
	}

	public String getRejectedDescription() {
		StringBuilder sb= new StringBuilder();
		sb.append("@@ -"); //$NON-NLS-1$
		sb.append(Integer.toString(this.fOldStart));
		sb.append(',');
		sb.append(Integer.toString(this.fOldLength));
		sb.append(" +"); //$NON-NLS-1$
		sb.append(Integer.toString(this.fNewStart));
		sb.append(',');
		sb.append(Integer.toString(this.fNewLength));
		sb.append(" @@"); //$NON-NLS-1$
		return sb.toString();
	}

	public int getHunkType(boolean reverse) {
		if (reverse) {
			if (this.hunkType == FilePatch2.ADDITION)
				return FilePatch2.DELETION;
			if (this.hunkType == FilePatch2.DELETION)
				return FilePatch2.ADDITION;
		}
		return this.hunkType;
	}

	void setHunkType(int hunkType) {
		this.hunkType = hunkType;
	}

	public String[] getLines() {
		return this.fLines;
	}

	@Override
	public String[] getUnifiedLines() {
		String[] ret = new String[this.fLines.length];
		System.arraycopy(this.fLines, 0, ret, 0, this.fLines.length);
		return ret;
	}

	/**
	 * Set the parent of this hunk. This method
	 * should only be invoked from {@link FilePatch2#add(Hunk)}
	 * @param diff the parent of this hunk
	 */
	void setParent(FilePatch2 diff) {
		if (this.fParent == diff)
			return;
		if (this.fParent != null)
			this.fParent.remove(this);
		this.fParent = diff;
	}

	public FilePatch2 getParent() {
		return this.fParent;
	}

	/*
	 * Tries to apply the given hunk on the specified lines.
	 * The parameter shift is added to the line numbers given
	 * in the hunk.
	 */
	public boolean tryPatch(PatchConfiguration configuration, List<String> lines, int shift, int fuzz) {
		boolean reverse = configuration.isReversed();
		int pos = getStart(reverse) + shift;
		List<String> contextLines = new ArrayList<>();
		boolean contextLinesMatched = true;
		boolean precedingLinesChecked = false;
		for (int i= 0; i < this.fLines.length; i++) {
			String s = this.fLines[i];
			Assert.isTrue(s.length() > 0);
			String line = s.substring(1);
			char controlChar = s.charAt(0);

			if (controlChar == ' ') {	// context lines

				if (pos < 0 || pos >= lines.size())
					return false;
				contextLines.add(line);
				if (linesMatch(configuration, line, lines.get(pos))) {
					pos++;
					continue;
				} else if (fuzz > 0) {
					// doesn't match, use the fuzz factor
					contextLinesMatched = false;
					pos++;
					continue;
				}
				return false;
			} else if (isDeletedDelimeter(controlChar, reverse)) {
				// deleted lines

				if (precedingLinesChecked && !contextLinesMatched && contextLines.size() > 0)
					// context lines inside hunk don't match
					return false;

				// check following context lines if exist
				// use the fuzz factor if needed
				if (!precedingLinesChecked
						&& !contextLinesMatched
						&& contextLines.size() >= fuzz
						&& !checkPrecedingContextLines(configuration, lines,
								fuzz, pos, contextLines))
					return false;
				// else if there is less or equal context line to the fuzz
				// factor we ignore them all and treat as matching

				precedingLinesChecked = true;
				contextLines.clear();
				contextLinesMatched = true;

				if (pos < 0 || pos >= lines.size()) // out of the file
					return false;
				if (linesMatch(configuration, line, lines.get(pos))) {
					pos++;
					continue; // line matched, continue with the next one
				}

				// We must remove all lines at once, return false if this
				// fails. In other words, all lines considered for deletion
				// must be found one by one.
				return false;
			} else if (isAddedDelimeter(controlChar, reverse)) {

				if (precedingLinesChecked && !contextLinesMatched && contextLines.size() > 0)
					return false;

				if (!precedingLinesChecked
						&& !contextLinesMatched
						&& contextLines.size() >= fuzz
						&& !checkPrecedingContextLines(configuration, lines,
								fuzz, pos, contextLines))
					return false;

				precedingLinesChecked = true;
				contextLines.clear();
				contextLinesMatched = true;

				// we don't have to do anything more for a 'try'
			} else
				Assert.isTrue(false, "tryPatch: unknown control character: " + controlChar); //$NON-NLS-1$
		}

		// check following context lines if exist
		if (!contextLinesMatched
				&& fuzz > 0
				&& contextLines.size() > fuzz
				&& !checkFollowingContextLines(configuration, lines, fuzz, pos,
						contextLines))
			return false;

		return true;
	}

	private boolean checkPrecedingContextLines(
			PatchConfiguration configuration, List<String> lines, int fuzz, int pos,
			List<String> contextLines) {
		// ignore from the beginning
		for (int j = fuzz; j < contextLines.size(); j++) {
			if (!linesMatch(configuration, contextLines.get(j),
							lines.get(pos - contextLines.size() + j)))
				return false;
		}
		return true;
	}

	private boolean checkFollowingContextLines(
			PatchConfiguration configuration, List<String> lines, int fuzz, int pos,
			List<String> contextLines) {
		if (!contextLines.isEmpty()) {
			// ignore from the end
			for (int j = 0; j < contextLines.size() - fuzz; j++) {
				if (!linesMatch(configuration, contextLines.get(j),
						lines.get(pos - contextLines.size() + j)))
					return false;
			}
		}
		return true;
	}

	public int getStart(boolean after) {
		if (after) {
			return this.fNewStart;
		}
		return this.fOldStart;
	}

	public void setStart(int start, boolean after) {
		if (after) {
			this.fNewStart = start;
		} else {
			this.fOldStart = start;
		}
	}

	public int getLength(boolean after) {
		if (after) {
			return this.fNewLength;
		}
		return this.fOldLength;
	}

	private int getShift(boolean reverse) {
		if (reverse) {
			return this.fOldLength - this.fNewLength;
		}
		return this.fNewLength - this.fOldLength;
	}

	int doPatch(PatchConfiguration configuration, List<String> lines, int shift, int fuzz) {
		boolean reverse = configuration.isReversed();
		int pos = getStart(reverse) + shift;
		List<String> contextLines = new ArrayList<>();
		boolean contextLinesMatched = true;
		boolean precedingLinesChecked = false;
		String lineDelimiter = getLineDelimiter(lines);

		for (int i= 0; i < this.fLines.length; i++) {
			String s= this.fLines[i];
			Assert.isTrue(s.length() > 0);
			String line= s.substring(1);
			char controlChar= s.charAt(0);
			if (controlChar == ' ') {
				// context lines
					Assert.isTrue(pos < lines.size(), "doPatch: inconsistency in context"); //$NON-NLS-1$
					contextLines.add(line);
					if (linesMatch(configuration, line, lines.get(pos))) {
						pos++;
						continue;
					} else if (fuzz > 0) {
						// doesn't match, use the fuzz factor
						contextLinesMatched = false;
						pos++;
						continue;
					}
					Assert.isTrue(false, "doPatch: context doesn't match"); //$NON-NLS-1$
//					pos++;
			} else if (isDeletedDelimeter(controlChar, reverse)) {
				// deleted lines
				if (precedingLinesChecked && !contextLinesMatched && contextLines.size() > 0)
					// context lines inside hunk don't match
					Assert.isTrue(false, "doPatch: context lines inside hunk don't match"); //$NON-NLS-1$

				// check following context lines if exist
				// use the fuzz factor if needed
				if (!precedingLinesChecked
						&& !contextLinesMatched
						&& contextLines.size() >= fuzz
						&& !checkPrecedingContextLines(configuration, lines,
								fuzz, pos, contextLines))
					Assert.isTrue(false, "doPatch: preceding context lines don't match, even though fuzz factor has been used"); //$NON-NLS-1$;
				// else if there is less or equal context line to the fuzz
				// factor we ignore them all and treat as matching

				precedingLinesChecked = true;
				contextLines.clear();
				contextLinesMatched = true;

				lines.remove(pos);
			} else if (isAddedDelimeter(controlChar, reverse)) {
				// added lines
				if (precedingLinesChecked && !contextLinesMatched && contextLines.size() > 0)
					Assert.isTrue(false, "doPatch: context lines inside hunk don't match"); //$NON-NLS-1$

				if (!precedingLinesChecked
						&& !contextLinesMatched
						&& contextLines.size() >= fuzz
						&& !checkPrecedingContextLines(configuration, lines,
								fuzz, pos, contextLines))
					Assert.isTrue(false, "doPatch: preceding context lines don't match, even though fuzz factor has been used"); //$NON-NLS-1$;

				precedingLinesChecked = true;
				contextLines.clear();
				contextLinesMatched = true;

				// if the line contains a delimiter, use a proper one
				if (line.length() > LineReader.length(line))
					line = line.substring(0, LineReader.length(line)) + lineDelimiter;

				if (getLength(reverse) == 0 && pos+1 < lines.size())
					lines.add(pos+1, line);
				else
					lines.add(pos, line);
				pos++;
			} else
				Assert.isTrue(false, "doPatch: unknown control character: " + controlChar); //$NON-NLS-1$
		}
		return getShift(reverse);
	}

	private boolean isDeletedDelimeter(char controlChar, boolean reverse) {
		return (!reverse && controlChar == '-') || (reverse && controlChar == '+');
	}

	private boolean isAddedDelimeter(char controlChar, boolean reverse) {
		return (reverse && controlChar == '-') || (!reverse && controlChar == '+');
	}

	/*
	 * Compares two strings.
	 * If fIgnoreWhitespace is true whitespace is ignored.
	 */
	private boolean linesMatch(PatchConfiguration configuration, String line1, String line2) {
		if (configuration.isIgnoreWhitespace())
			return stripWhiteSpace(line1).equals(stripWhiteSpace(line2));
		if (isIgnoreLineDelimiter()) {
			int l1= LineReader.length(line1);
			int l2= LineReader.length(line2);
			if (l1 != l2)
				return false;
			return line1.regionMatches(0, line2, 0, l1);
		}
		return line1.equals(line2);
	}

	private boolean isIgnoreLineDelimiter() {
		return true;
	}

	private String getLineDelimiter(List<String> lines) {
		if (lines.size() > 0) {
			// get a line separator from the file being patched
			String line0 = lines.get(0);
			return line0.substring(LineReader.length(line0));
		} else if (this.fLines.length > 0) {
			// if the file doesn't exist use a line separator from the patch
			return this.fLines[0].substring(LineReader.length(this.fLines[0]));
		}
		return System.getProperty("line.separator"); //$NON-NLS-1$
	}

	/*
	 * Returns the given string with all whitespace characters removed.
	 * Whitespace is defined by <code>Character.isWhitespace(...)</code>.
	 */
	private String stripWhiteSpace(String s) {
		StringBuilder sb= new StringBuilder();
		int l= s.length();
		for (int i= 0; i < l; i++) {
			char c= s.charAt(i);
			if (!Character.isWhitespace(c))
				sb.append(c);
		}
		return sb.toString();
	}

	public String getContents(boolean isAfterState, boolean reverse) {
		StringBuilder result= new StringBuilder();
		for (int i= 0; i<this.fLines.length; i++) {
			String line= this.fLines[i];
			String rest= line.substring(1);
			char c = line.charAt(0);
			if (c == ' ') {
				result.append(rest);
			} else if (isDeletedDelimeter(c, reverse) && !isAfterState) {
				result.append(rest);
			} else if (isAddedDelimeter(c, reverse) && isAfterState) {
				result.append(rest);
			}
		}
		return result.toString();
	}

	@Override
	public String getLabel() {
		return getDescription();
	}

	@Override
	public int getStartPosition() {
		return getStart(false);
	}

	@Override
	public InputStream getOriginalContents() {
		String contents = getContents(false, false);
		return asInputStream(contents);
	}

	@Override
	public InputStream getPatchedContents() {
		String contents = getContents(true, false);
		return asInputStream(contents);
	}

	private InputStream asInputStream(String contents) {
		String charSet = getCharset();
		return FileDiffResult.asInputStream(contents, charSet);
	}

	void setCharset(String charset) {
		this.charset = charset;
	}

	/**
	 * {@inheritDoc}
	 * @deprecated This method can be called before the first attempt to apply
	 *             the hunk when it is impossible to determine the encoding and
	 *             in this case it always returns null. Please see
	 *             {@link IFilePatchResult#getCharset()} as a proper way to
	 *             obtain charset.
	 */
	@Deprecated
	@Override
	public String getCharset() {
		return this.charset;
	}

}
