/*
 * Copyright (C) 2008-2013, Google Inc. and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.diff;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.jgit.attributes.Attribute;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilterMarker;

/**
 * A value class representing a change to a file
 */
public class DiffEntry {
	/** Magical SHA1 used for file adds or deletes */
	static final AbbreviatedObjectId A_ZERO = AbbreviatedObjectId
			.fromObjectId(ObjectId.zeroId());

	/** Magical file name used for file adds or deletes. */
	public static final String DEV_NULL = "/dev/null"; //$NON-NLS-1$

	/** General type of change a single file-level patch describes. */
	public enum ChangeType {
		/** Add a new file to the project */
		ADD,

		/** Modify an existing file in the project (content and/or mode) */
		MODIFY,

		/** Delete an existing file from the project */
		DELETE,

		/** Rename an existing file to a new location */
		RENAME,

		/** Copy an existing file to a new location, keeping the original */
		COPY;
	}

	/** Specify the old or new side for more generalized access. */
	public enum Side {
		/** The old side of a DiffEntry. */
		OLD,

		/** The new side of a DiffEntry. */
		NEW;
	}

	/**
	 * Create an empty DiffEntry
	 */
	protected DiffEntry(){
		// reduce the visibility of the default constructor
	}

	/**
	 * Convert the TreeWalk into DiffEntry headers.
	 *
	 * @param walk
	 *            the TreeWalk to walk through. Must have exactly two trees.
	 * @return headers describing the changed files.
	 * @throws java.io.IOException
	 *             the repository cannot be accessed.
	 * @throws java.lang.IllegalArgumentException
	 *             When given TreeWalk doesn't have exactly two trees.
	 */
	public static List<DiffEntry> scan(TreeWalk walk) throws IOException {
		return scan(walk, false);
	}

	/**
	 * Convert the TreeWalk into DiffEntry headers, depending on
	 * {@code includeTrees} it will add tree objects into result or not.
	 *
	 * @param walk
	 *            the TreeWalk to walk through. Must have exactly two trees and
	 *            when {@code includeTrees} parameter is {@code true} it can't
	 *            be recursive.
	 * @param includeTrees
	 *            include tree objects.
	 * @return headers describing the changed files.
	 * @throws java.io.IOException
	 *             the repository cannot be accessed.
	 * @throws java.lang.IllegalArgumentException
	 *             when {@code includeTrees} is true and given TreeWalk is
	 *             recursive. Or when given TreeWalk doesn't have exactly two
	 *             trees
	 */
	public static List<DiffEntry> scan(TreeWalk walk, boolean includeTrees)
			throws IOException {
		return scan(walk, includeTrees, null);
	}

	/**
	 * Convert the TreeWalk into DiffEntry headers, depending on
	 * {@code includeTrees} it will add tree objects into result or not.
	 *
	 * @param walk
	 *            the TreeWalk to walk through. Must have exactly two trees and
	 *            when {@code includeTrees} parameter is {@code true} it can't
	 *            be recursive.
	 * @param includeTrees
	 *            include tree objects.
	 * @param markTreeFilters
	 *            array of tree filters which will be tested for each entry. If
	 *            an entry matches, the entry will later return true when
	 *            queried through {{@link #isMarked(int)} (with the index from
	 *            this passed array).
	 * @return headers describing the changed files.
	 * @throws java.io.IOException
	 *             the repository cannot be accessed.
	 * @throws java.lang.IllegalArgumentException
	 *             when {@code includeTrees} is true and given TreeWalk is
	 *             recursive. Or when given TreeWalk doesn't have exactly two
	 *             trees
	 * @since 2.3
	 */
	public static List<DiffEntry> scan(TreeWalk walk, boolean includeTrees,
			TreeFilter[] markTreeFilters)
			throws IOException {
		if (walk.getTreeCount() != 2)
			throw new IllegalArgumentException(
					JGitText.get().treeWalkMustHaveExactlyTwoTrees);
		if (includeTrees && walk.isRecursive())
			throw new IllegalArgumentException(
					JGitText.get().cannotBeRecursiveWhenTreesAreIncluded);

		TreeFilterMarker treeFilterMarker;
		if (markTreeFilters != null && markTreeFilters.length > 0)
			treeFilterMarker = new TreeFilterMarker(markTreeFilters);
		else
			treeFilterMarker = null;

		List<DiffEntry> r = new ArrayList<>();
		MutableObjectId idBuf = new MutableObjectId();
		while (walk.next()) {
			DiffEntry entry = new DiffEntry();

			walk.getObjectId(idBuf, 0);
			entry.oldId = AbbreviatedObjectId.fromObjectId(idBuf);

			walk.getObjectId(idBuf, 1);
			entry.newId = AbbreviatedObjectId.fromObjectId(idBuf);

			entry.oldMode = walk.getFileMode(0);
			entry.newMode = walk.getFileMode(1);
			entry.newPath = entry.oldPath = walk.getPathString();

			if (walk.getAttributesNodeProvider() != null) {
				entry.diffAttribute = walk.getAttributes()
						.get(Constants.ATTR_DIFF);
			}

			if (treeFilterMarker != null)
				entry.treeFilterMarks = treeFilterMarker.getMarks(walk);

			if (entry.oldMode == FileMode.MISSING) {
				entry.oldPath = DiffEntry.DEV_NULL;
				entry.changeType = ChangeType.ADD;
				r.add(entry);

			} else if (entry.newMode == FileMode.MISSING) {
				entry.newPath = DiffEntry.DEV_NULL;
				entry.changeType = ChangeType.DELETE;
				r.add(entry);

			} else if (!entry.oldId.equals(entry.newId)) {
				entry.changeType = ChangeType.MODIFY;
				if (RenameDetector.sameType(entry.oldMode, entry.newMode))
					r.add(entry);
				else
					r.addAll(breakModify(entry));
			} else if (entry.oldMode != entry.newMode) {
				entry.changeType = ChangeType.MODIFY;
				r.add(entry);
			}

			if (includeTrees && walk.isSubtree())
				walk.enterSubtree();
		}
		return r;
	}

	static DiffEntry add(String path, AnyObjectId id) {
		DiffEntry e = new DiffEntry();
		e.oldId = A_ZERO;
		e.oldMode = FileMode.MISSING;
		e.oldPath = DEV_NULL;

		e.newId = AbbreviatedObjectId.fromObjectId(id);
		e.newMode = FileMode.REGULAR_FILE;
		e.newPath = path;
		e.changeType = ChangeType.ADD;
		return e;
	}

	static DiffEntry delete(String path, AnyObjectId id) {
		DiffEntry e = new DiffEntry();
		e.oldId = AbbreviatedObjectId.fromObjectId(id);
		e.oldMode = FileMode.REGULAR_FILE;
		e.oldPath = path;

		e.newId = A_ZERO;
		e.newMode = FileMode.MISSING;
		e.newPath = DEV_NULL;
		e.changeType = ChangeType.DELETE;
		return e;
	}

	static DiffEntry modify(String path) {
		DiffEntry e = new DiffEntry();
		e.oldMode = FileMode.REGULAR_FILE;
		e.oldPath = path;

		e.newMode = FileMode.REGULAR_FILE;
		e.newPath = path;
		e.changeType = ChangeType.MODIFY;
		return e;
	}

	/**
	 * Breaks apart a DiffEntry into two entries, one DELETE and one ADD.
	 *
	 * @param entry
	 *            the DiffEntry to break apart.
	 * @return a list containing two entries. Calling {@link #getChangeType()}
	 *         on the first entry will return ChangeType.DELETE. Calling it on
	 *         the second entry will return ChangeType.ADD.
	 */
	static List<DiffEntry> breakModify(DiffEntry entry) {
		DiffEntry del = new DiffEntry();
		del.oldId = entry.getOldId();
		del.oldMode = entry.getOldMode();
		del.oldPath = entry.getOldPath();

		del.newId = A_ZERO;
		del.newMode = FileMode.MISSING;
		del.newPath = DiffEntry.DEV_NULL;
		del.changeType = ChangeType.DELETE;
		del.diffAttribute = entry.diffAttribute;

		DiffEntry add = new DiffEntry();
		add.oldId = A_ZERO;
		add.oldMode = FileMode.MISSING;
		add.oldPath = DiffEntry.DEV_NULL;

		add.newId = entry.getNewId();
		add.newMode = entry.getNewMode();
		add.newPath = entry.getNewPath();
		add.changeType = ChangeType.ADD;
		add.diffAttribute = entry.diffAttribute;
		return Arrays.asList(del, add);
	}

	static DiffEntry pair(ChangeType changeType, DiffEntry src, DiffEntry dst,
			int score) {
		DiffEntry r = new DiffEntry();

		r.oldId = src.oldId;
		r.oldMode = src.oldMode;
		r.oldPath = src.oldPath;

		r.newId = dst.newId;
		r.newMode = dst.newMode;
		r.newPath = dst.newPath;
		r.diffAttribute = dst.diffAttribute;

		r.changeType = changeType;
		r.score = score;

		r.treeFilterMarks = src.treeFilterMarks | dst.treeFilterMarks;

		return r;
	}

	/** File name of the old (pre-image). */
	protected String oldPath;

	/** File name of the new (post-image). */
	protected String newPath;

	/**
	 * diff filter attribute
	 *
	 * @since 4.11
	 */
	protected Attribute diffAttribute;

	/** Old mode of the file, if described by the patch, else null. */
	protected FileMode oldMode;

	/** New mode of the file, if described by the patch, else null. */
	protected FileMode newMode;

	/** General type of change indicated by the patch. */
	protected ChangeType changeType;

	/** Similarity score if {@link #changeType} is a copy or rename. */
	protected int score;

	/** ObjectId listed on the index line for the old (pre-image) */
	protected AbbreviatedObjectId oldId;

	/** ObjectId listed on the index line for the new (post-image) */
	protected AbbreviatedObjectId newId;

	/**
	 * Bitset for marked flags of tree filters passed to
	 * {@link #scan(TreeWalk, boolean, TreeFilter...)}
	 */
	private int treeFilterMarks = 0;

	/**
	 * Get the old name associated with this file.
	 * <p>
	 * The meaning of the old name can differ depending on the semantic meaning
	 * of this patch:
	 * <ul>
	 * <li><i>file add</i>: always <code>/dev/null</code></li>
	 * <li><i>file modify</i>: always {@link #getNewPath()}</li>
	 * <li><i>file delete</i>: always the file being deleted</li>
	 * <li><i>file copy</i>: source file the copy originates from</li>
	 * <li><i>file rename</i>: source file the rename originates from</li>
	 * </ul>
	 *
	 * @return old name for this file.
	 */
	public String getOldPath() {
		return oldPath;
	}

	/**
	 * Get the new name associated with this file.
	 * <p>
	 * The meaning of the new name can differ depending on the semantic meaning
	 * of this patch:
	 * <ul>
	 * <li><i>file add</i>: always the file being created</li>
	 * <li><i>file modify</i>: always {@link #getOldPath()}</li>
	 * <li><i>file delete</i>: always <code>/dev/null</code></li>
	 * <li><i>file copy</i>: destination file the copy ends up at</li>
	 * <li><i>file rename</i>: destination file the rename ends up at</li>
	 * </ul>
	 *
	 * @return new name for this file.
	 */
	public String getNewPath() {
		return newPath;
	}

	/**
	 * Get the path associated with this file.
	 *
	 * @param side
	 *            which path to obtain.
	 * @return name for this file.
	 */
	public String getPath(Side side) {
		return side == Side.OLD ? getOldPath() : getNewPath();
	}

	/**
	 * @return the {@link Attribute} determining filters to be applied.
	 * @since 4.11
	 */
	public Attribute getDiffAttribute() {
		return diffAttribute;
	}

	/**
	 * Get the old file mode
	 *
	 * @return the old file mode, if described in the patch
	 */
	public FileMode getOldMode() {
		return oldMode;
	}

	/**
	 * Get the new file mode
	 *
	 * @return the new file mode, if described in the patch
	 */
	public FileMode getNewMode() {
		return newMode;
	}

	/**
	 * Get the mode associated with this file.
	 *
	 * @param side
	 *            which mode to obtain.
	 * @return the mode.
	 */
	public FileMode getMode(Side side) {
		return side == Side.OLD ? getOldMode() : getNewMode();
	}

	/**
	 * Get the change type
	 *
	 * @return the type of change this patch makes on {@link #getNewPath()}
	 */
	public ChangeType getChangeType() {
		return changeType;
	}

	/**
	 * Get similarity score
	 *
	 * @return similarity score between {@link #getOldPath()} and
	 *         {@link #getNewPath()} if {@link #getChangeType()} is
	 *         {@link org.eclipse.jgit.diff.DiffEntry.ChangeType#COPY} or
	 *         {@link org.eclipse.jgit.diff.DiffEntry.ChangeType#RENAME}.
	 */
	public int getScore() {
		return score;
	}

	/**
	 * Get the old object id from the <code>index</code>.
	 *
	 * @return the object id; null if there is no index line
	 */
	public AbbreviatedObjectId getOldId() {
		return oldId;
	}

	/**
	 * Get the new object id from the <code>index</code>.
	 *
	 * @return the object id; null if there is no index line
	 */
	public AbbreviatedObjectId getNewId() {
		return newId;
	}

	/**
	 * Whether the mark tree filter with the specified index matched during scan
	 * or not, see {@link #scan(TreeWalk, boolean, TreeFilter...)}. Example:
	 * <p>
	 *
	 * <pre>
	 * TreeFilter filterA = ...;
	 * TreeFilter filterB = ...;
	 * List&lt;DiffEntry&gt; entries = DiffEntry.scan(walk, false, filterA, filterB);
	 * DiffEntry entry = entries.get(0);
	 * boolean filterAMatched = entry.isMarked(0);
	 * boolean filterBMatched = entry.isMarked(1);
	 * </pre>
	 * <p>
	 * Note that 0 corresponds to filterA because it was the first filter that
	 * was passed to scan.
	 * <p>
	 * To query more than one flag at once, see {@link #getTreeFilterMarks()}.
	 *
	 * @param index
	 *            the index of the tree filter to check for (must be between 0
	 *            and {@link java.lang.Integer#SIZE}).
	 * @since 2.3
	 * @return a boolean.
	 */
	public boolean isMarked(int index) {
		return (treeFilterMarks & (1L << index)) != 0;
	}

	/**
	 * Get the raw tree filter marks, as set during
	 * {@link #scan(TreeWalk, boolean, TreeFilter...)}. See
	 * {@link #isMarked(int)} to query each mark individually.
	 *
	 * @return the bitset of tree filter marks
	 * @since 2.3
	 */
	public int getTreeFilterMarks() {
		return treeFilterMarks;
	}

	/**
	 * Get the object id.
	 *
	 * @param side
	 *            the side of the id to get.
	 * @return the object id; null if there is no index line
	 */
	public AbbreviatedObjectId getId(Side side) {
		return side == Side.OLD ? getOldId() : getNewId();
	}

	/** {@inheritDoc} */
	@SuppressWarnings("nls")
	@Override
	public String toString() {
		StringBuilder buf = new StringBuilder();
		buf.append("DiffEntry[");
		buf.append(changeType);
		buf.append(" ");
		switch (changeType) {
		case ADD:
			buf.append(newPath);
			break;
		case COPY:
			buf.append(oldPath + "->" + newPath);
			break;
		case DELETE:
			buf.append(oldPath);
			break;
		case MODIFY:
			buf.append(oldPath);
			break;
		case RENAME:
			buf.append(oldPath + "->" + newPath);
			break;
		}
		buf.append("]");
		return buf.toString();
	}
}
