/*
 * 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 org.eclipse.jgit.lib.PersonIdent} for the presumed
	 *            author and time
	 * @param committer
	 *            the {@link org.eclipse.jgit.lib.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
	 *            a message.
	 * @param changeId
	 *            a Change-Id.
	 * @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
	 *            a message.
	 * @param changeId
	 *            a Change-Id.
	 * @param replaceExisting
	 *            a boolean.
	 * @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;
			}
			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',
					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
	 *            a 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;
	}
}
