/*
 * Copyright (C) 2010, Robin Rosenberg
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.eclipse.jgit.util;

import java.util.regex.Pattern;

import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;

/**
 * Utilities for creating and working with Change-Id's, like the one used by
 * Gerrit Code Review.
 * <p>
 * A Change-Id is a SHA-1 computed from the content of a commit, in a similar
 * fashion to how the commit id is computed. Unlike the commit id a Change-Id is
 * retained in the commit and subsequent revised commits in the footer of the
 * commit text.
 */
public class ChangeIdUtil {

	static final String CHANGE_ID = "Change-Id:"; //$NON-NLS-1$

	// package-private so the unit test can test this part only
	@SuppressWarnings("nls")
	static String clean(String msg) {
		return msg.//
				replaceAll("(?i)(?m)^Signed-off-by:.*$\n?", "").// //$NON-NLS-1$
				replaceAll("(?m)^#.*$\n?", "").// //$NON-NLS-1$
				replaceAll("(?m)\n\n\n+", "\\\n").// //$NON-NLS-1$
				replaceAll("\\n*$", "").// //$NON-NLS-1$
				replaceAll("(?s)\ndiff --git.*", "").// //$NON-NLS-1$
				trim();
	}

	/**
	 * Compute a Change-Id.
	 *
	 * @param treeId
	 *            The id of the tree that would be committed
	 * @param firstParentId
	 *            parent id of previous commit or null
	 * @param author
	 *            the {@link PersonIdent} for the presumed author and time
	 * @param committer
	 *            the {@link PersonIdent} for the presumed committer and time
	 * @param message
	 *            The commit message
	 * @return the change id SHA1 string (without the 'I') or null if the
	 *         message is not complete enough
	 */
	public static ObjectId computeChangeId(final ObjectId treeId,
			final ObjectId firstParentId, final PersonIdent author,
			final PersonIdent committer, final String message) {
		String cleanMessage = clean(message);
		if (cleanMessage.length() == 0)
			return null;
		StringBuilder b = new StringBuilder();
		b.append("tree "); //$NON-NLS-1$
		b.append(ObjectId.toString(treeId));
		b.append("\n"); //$NON-NLS-1$
		if (firstParentId != null) {
			b.append("parent "); //$NON-NLS-1$
			b.append(ObjectId.toString(firstParentId));
			b.append("\n"); //$NON-NLS-1$
		}
		b.append("author "); //$NON-NLS-1$
		b.append(author.toExternalString());
		b.append("\n"); //$NON-NLS-1$
		b.append("committer "); //$NON-NLS-1$
		b.append(committer.toExternalString());
		b.append("\n\n"); //$NON-NLS-1$
		b.append(cleanMessage);
		try (ObjectInserter f = new ObjectInserter.Formatter()) {
			return f.idFor(Constants.OBJ_COMMIT, Constants.encode(b.toString()));
		}
	}

	private static final Pattern issuePattern = Pattern
			.compile("^(Bug|Issue)[a-zA-Z0-9-]*:.*$"); //$NON-NLS-1$

	private static final Pattern footerPattern = Pattern
			.compile("(^[a-zA-Z0-9-]+:(?!//).*$)"); //$NON-NLS-1$

	private static final Pattern changeIdPattern = Pattern
			.compile("(^" + CHANGE_ID + " *I[a-f0-9]{40}$)"); //$NON-NLS-1$ //$NON-NLS-2$

	private static final Pattern includeInFooterPattern = Pattern
			.compile("^[ \\[].*$"); //$NON-NLS-1$

	private static final Pattern trailingWhitespace = Pattern.compile("\\s+$"); //$NON-NLS-1$

	/**
	 * Find the right place to insert a Change-Id and return it.
	 * <p>
	 * The Change-Id is inserted before the first footer line but after a Bug
	 * line.
	 *
	 * @param message
	 * @param changeId
	 * @return a commit message with an inserted Change-Id line
	 */
	public static String insertId(String message, ObjectId changeId) {
		return insertId(message, changeId, false);
	}

	/**
	 * Find the right place to insert a Change-Id and return it.
	 * <p>
	 * If no Change-Id is found the Change-Id is inserted before
	 * the first footer line but after a Bug line.
	 *
	 * If Change-Id is found and replaceExisting is set to false,
	 * the message is unchanged.
	 *
	 * If Change-Id is found and replaceExisting is set to true,
	 * the Change-Id is replaced with {@code changeId}.
	 *
	 * @param message
	 * @param changeId
	 * @param replaceExisting
	 * @return a commit message with an inserted Change-Id line
	 */
	public static String insertId(String message, ObjectId changeId,
			boolean replaceExisting) {
		int indexOfChangeId = indexOfChangeId(message, "\n"); //$NON-NLS-1$
		if (indexOfChangeId > 0) {
			if (!replaceExisting)
				return message;
			else {
				StringBuilder ret = new StringBuilder(message.substring(0,
						indexOfChangeId));
				ret.append(CHANGE_ID);
				ret.append(" I"); //$NON-NLS-1$
				ret.append(ObjectId.toString(changeId));
				int indexOfNextLineBreak = message.indexOf("\n", //$NON-NLS-1$
						indexOfChangeId);
				if (indexOfNextLineBreak > 0)
					ret.append(message.substring(indexOfNextLineBreak));
				return ret.toString();
			}
		}

		String[] lines = message.split("\n"); //$NON-NLS-1$
		int footerFirstLine = indexOfFirstFooterLine(lines);
		int insertAfter = footerFirstLine;
		for (int i = footerFirstLine; i < lines.length; ++i) {
			if (issuePattern.matcher(lines[i]).matches()) {
				insertAfter = i + 1;
				continue;
			}
			break;
		}
		StringBuilder ret = new StringBuilder();
		int i = 0;
		for (; i < insertAfter; ++i) {
			ret.append(lines[i]);
			ret.append("\n"); //$NON-NLS-1$
		}
		if (insertAfter == lines.length && insertAfter == footerFirstLine)
			ret.append("\n"); //$NON-NLS-1$
		ret.append(CHANGE_ID);
		ret.append(" I"); //$NON-NLS-1$
		ret.append(ObjectId.toString(changeId));
		ret.append("\n"); //$NON-NLS-1$
		for (; i < lines.length; ++i) {
			ret.append(lines[i]);
			ret.append("\n"); //$NON-NLS-1$
		}
		return ret.toString();
	}

	/**
	 * Return the index in the String {@code message} where the Change-Id entry
	 * in the footer begins. If there are more than one entries matching the
	 * pattern, return the index of the last one in the last section. Because of
	 * Bug: 400818 we release the constraint here that a footer must contain
	 * only lines matching {@code footerPattern}.
	 *
	 * @param message
	 * @param delimiter
	 *            the line delimiter, like "\n" or "\r\n", needed to find the
	 *            footer
	 * @return the index of the ChangeId footer in the message, or -1 if no
	 *         ChangeId footer available
	 */
	public static int indexOfChangeId(String message, String delimiter) {
		String[] lines = message.split(delimiter);
		if (lines.length == 0)
			return -1;
		int indexOfChangeIdLine = 0;
		boolean inFooter = false;
		for (int i = lines.length - 1; i >= 0; --i) {
			if (!inFooter && isEmptyLine(lines[i]))
				continue;
			inFooter = true;
			if (changeIdPattern.matcher(trimRight(lines[i])).matches()) {
				indexOfChangeIdLine = i;
				break;
			} else if (isEmptyLine(lines[i]) || i == 0)
				return -1;
		}
		int indexOfChangeIdLineinString = 0;
		for (int i = 0; i < indexOfChangeIdLine; ++i)
			indexOfChangeIdLineinString += lines[i].length()
					+ delimiter.length();
		return indexOfChangeIdLineinString
				+ lines[indexOfChangeIdLine].indexOf(CHANGE_ID);
	}

	private static boolean isEmptyLine(String line) {
		return line.trim().length() == 0;
	}

	private static String trimRight(String s) {
		return trailingWhitespace.matcher(s).replaceAll(""); //$NON-NLS-1$
	}

	/**
	 * Find the index of the first line of the footer paragraph in an array of
	 * the lines, or lines.length if no footer is available
	 *
	 * @param lines
	 *            the commit message split into lines and the line delimiters
	 *            stripped off
	 * @return the index of the first line of the footer paragraph, or
	 *         lines.length if no footer is available
	 */
	public static int indexOfFirstFooterLine(String[] lines) {
		int footerFirstLine = lines.length;
		for (int i = lines.length - 1; i > 1; --i) {
			if (footerPattern.matcher(lines[i]).matches()) {
				footerFirstLine = i;
				continue;
			}
			if (footerFirstLine != lines.length && lines[i].length() == 0)
				break;
			if (footerFirstLine != lines.length
					&& includeInFooterPattern.matcher(lines[i]).matches()) {
				footerFirstLine = i + 1;
				continue;
			}
			footerFirstLine = lines.length;
			break;
		}
		return footerFirstLine;
	}
}
