/*
 * Copyright 2013 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.git;

import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_SIDE_BAND_64K;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.ReceiveCommand.Result;
import org.eclipse.jgit.transport.ReceiveCommand.Type;
import org.eclipse.jgit.transport.ReceivePack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.Constants;
import com.gitblit.Keys;
import com.gitblit.extensions.PatchsetHook;
import com.gitblit.manager.IGitblit;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.TicketModel;
import com.gitblit.models.TicketModel.Change;
import com.gitblit.models.TicketModel.Field;
import com.gitblit.models.TicketModel.Patchset;
import com.gitblit.models.TicketModel.PatchsetType;
import com.gitblit.models.TicketModel.Status;
import com.gitblit.models.UserModel;
import com.gitblit.tickets.BranchTicketService;
import com.gitblit.tickets.ITicketService;
import com.gitblit.tickets.TicketMilestone;
import com.gitblit.tickets.TicketNotifier;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.DiffUtils;
import com.gitblit.utils.DiffUtils.DiffStat;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.JGitUtils.MergeResult;
import com.gitblit.utils.JGitUtils.MergeStatus;
import com.gitblit.utils.RefLogUtils;
import com.gitblit.utils.StringUtils;
import com.google.common.collect.Lists;


/**
 * PatchsetReceivePack processes receive commands and allows for creating, updating,
 * and closing Gitblit tickets.  It also executes Groovy pre- and post- receive
 * hooks.
 *
 * The patchset mechanism defined in this class is based on the ReceiveCommits class
 * from the Gerrit code review server.
 *
 * The general execution flow is:
 * <ol>
 *    <li>onPreReceive()</li>
 *    <li>executeCommands()</li>
 *    <li>onPostReceive()</li>
 * </ol>
 *
 * @author Android Open Source Project
 * @author James Moger
 *
 */
public class PatchsetReceivePack extends GitblitReceivePack {

	protected static final List<String> MAGIC_REFS = Arrays.asList(Constants.R_FOR, Constants.R_TICKET);

	protected static final Pattern NEW_PATCHSET =
			Pattern.compile("^refs/tickets/(?:[0-9a-zA-Z][0-9a-zA-Z]/)?([1-9][0-9]*)(?:/new)?$");

	private static final Logger LOGGER = LoggerFactory.getLogger(PatchsetReceivePack.class);

	protected final ITicketService ticketService;

	protected final TicketNotifier ticketNotifier;

	private boolean requireMergeablePatchset;

	public PatchsetReceivePack(IGitblit gitblit, Repository db, RepositoryModel repository, UserModel user) {
		super(gitblit, db, repository, user);
		this.ticketService = gitblit.getTicketService();
		this.ticketNotifier = ticketService.createNotifier();
	}

	/** Returns the patchset ref root from the ref */
	private String getPatchsetRef(String refName) {
		for (String patchRef : MAGIC_REFS) {
			if (refName.startsWith(patchRef)) {
				return patchRef;
			}
		}
		return null;
	}

	/** Checks if the supplied ref name is a patchset ref */
	private boolean isPatchsetRef(String refName) {
		return !StringUtils.isEmpty(getPatchsetRef(refName));
	}

	/** Checks if the supplied ref name is a change ref */
	private boolean isTicketRef(String refName) {
		return refName.startsWith(Constants.R_TICKETS_PATCHSETS);
	}

	/** Extracts the integration branch from the ref name */
	private String getIntegrationBranch(String refName) {
		String patchsetRef = getPatchsetRef(refName);
		String branch = refName.substring(patchsetRef.length());
		if (branch.indexOf('%') > -1) {
			branch = branch.substring(0, branch.indexOf('%'));
		}

		String defaultBranch = "master";
		try {
			defaultBranch = getRepository().getBranch();
		} catch (Exception e) {
			LOGGER.error("failed to determine default branch for " + repository.name, e);
		}

		if (!StringUtils.isEmpty(getRepositoryModel().mergeTo)) {
			// repository settings specifies a default integration branch
			defaultBranch = Repository.shortenRefName(getRepositoryModel().mergeTo);
		}

		long ticketId = 0L;
		try {
			ticketId = Long.parseLong(branch);
		} catch (Exception e) {
			// not a number
		}
		if (ticketId > 0 || branch.equalsIgnoreCase("default") || branch.equalsIgnoreCase("new")) {
			return defaultBranch;
		}
		return branch;
	}

	/** Extracts the ticket id from the ref name */
	private long getTicketId(String refName) {
		if (refName.indexOf('%') > -1) {
			refName = refName.substring(0, refName.indexOf('%'));
		}
		if (refName.startsWith(Constants.R_FOR)) {
			String ref = refName.substring(Constants.R_FOR.length());
			try {
				return Long.parseLong(ref);
			} catch (Exception e) {
				// not a number
			}
		} else if (refName.startsWith(Constants.R_TICKET) ||
				refName.startsWith(Constants.R_TICKETS_PATCHSETS)) {
			return PatchsetCommand.getTicketNumber(refName);
		}
		return 0L;
	}

	/** Returns true if the ref namespace exists */
	private boolean hasRefNamespace(String ref) {
		Map<String, Ref> blockingFors;
		try {
			blockingFors = getRepository().getRefDatabase().getRefs(ref);
		} catch (IOException err) {
			sendError("Cannot scan refs in {0}", repository.name);
			LOGGER.error("Error!", err);
			return true;
		}
		if (!blockingFors.isEmpty()) {
			sendError("{0} needs the following refs removed to receive patchsets: {1}",
					repository.name, blockingFors.keySet());
			return true;
		}
		return false;
	}

	/** Removes change ref receive commands */
	private List<ReceiveCommand> excludeTicketCommands(Collection<ReceiveCommand> commands) {
		List<ReceiveCommand> filtered = new ArrayList<ReceiveCommand>();
		for (ReceiveCommand cmd : commands) {
			if (!isTicketRef(cmd.getRefName())) {
				// this is not a ticket ref update
				filtered.add(cmd);
			}
		}
		return filtered;
	}

	/** Removes patchset receive commands for pre- and post- hook integrations */
	private List<ReceiveCommand> excludePatchsetCommands(Collection<ReceiveCommand> commands) {
		List<ReceiveCommand> filtered = new ArrayList<ReceiveCommand>();
		for (ReceiveCommand cmd : commands) {
			if (!isPatchsetRef(cmd.getRefName())) {
				// this is a non-patchset ref update
				filtered.add(cmd);
			}
		}
		return filtered;
	}

	/**	Process receive commands EXCEPT for Patchset commands. */
	@Override
	public void onPreReceive(ReceivePack rp, Collection<ReceiveCommand> commands) {
		Collection<ReceiveCommand> filtered = excludePatchsetCommands(commands);
		super.onPreReceive(rp, filtered);
	}

	/**	Process receive commands EXCEPT for Patchset commands. */
	@Override
	public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) {
		Collection<ReceiveCommand> filtered = excludePatchsetCommands(commands);
		super.onPostReceive(rp, filtered);

		// send all queued ticket notifications after processing all patchsets
		ticketNotifier.sendAll();
	}

	@Override
	protected void validateCommands() {
		// workaround for JGit's awful scoping choices
		//
		// set the patchset refs to OK to bypass checks in the super implementation
		for (final ReceiveCommand cmd : filterCommands(Result.NOT_ATTEMPTED)) {
			if (isPatchsetRef(cmd.getRefName())) {
				if (cmd.getType() == ReceiveCommand.Type.CREATE) {
					cmd.setResult(Result.OK);
				}
			}
		}

		super.validateCommands();
	}

	/** Execute commands to update references. */
	@Override
	protected void executeCommands() {
		// we process patchsets unless the user is pushing something special
		boolean processPatchsets = true;
		for (ReceiveCommand cmd : filterCommands(Result.NOT_ATTEMPTED)) {
			if (ticketService instanceof BranchTicketService
					&& BranchTicketService.BRANCH.equals(cmd.getRefName())) {
				// the user is pushing an update to the BranchTicketService data
				processPatchsets = false;
			}
		}

		// workaround for JGit's awful scoping choices
		//
		// reset the patchset refs to NOT_ATTEMPTED (see validateCommands)
		for (ReceiveCommand cmd : filterCommands(Result.OK)) {
			if (isPatchsetRef(cmd.getRefName())) {
				cmd.setResult(Result.NOT_ATTEMPTED);
			} else if (ticketService instanceof BranchTicketService
					&& BranchTicketService.BRANCH.equals(cmd.getRefName())) {
				// the user is pushing an update to the BranchTicketService data
				processPatchsets = false;
			}
		}

		List<ReceiveCommand> toApply = filterCommands(Result.NOT_ATTEMPTED);
		if (toApply.isEmpty()) {
			return;
		}

		ProgressMonitor updating = NullProgressMonitor.INSTANCE;
		boolean sideBand = isCapabilityEnabled(CAPABILITY_SIDE_BAND_64K);
		if (sideBand) {
			SideBandProgressMonitor pm = new SideBandProgressMonitor(msgOut);
			pm.setDelayStart(250, TimeUnit.MILLISECONDS);
			updating = pm;
		}

		BatchRefUpdate batch = getRepository().getRefDatabase().newBatchUpdate();
		batch.setAllowNonFastForwards(isAllowNonFastForwards());
		batch.setRefLogIdent(getRefLogIdent());
		batch.setRefLogMessage("push", true);

		ReceiveCommand patchsetRefCmd = null;
		PatchsetCommand patchsetCmd = null;
		for (ReceiveCommand cmd : toApply) {
			if (Result.NOT_ATTEMPTED != cmd.getResult()) {
				// Already rejected by the core receive process.
				continue;
			}

			if (isPatchsetRef(cmd.getRefName()) && processPatchsets) {

				if (ticketService == null) {
					sendRejection(cmd, "Sorry, the ticket service is unavailable and can not accept patchsets at this time.");
					continue;
				}

				if (!ticketService.isReady()) {
					sendRejection(cmd, "Sorry, the ticket service can not accept patchsets at this time.");
					continue;
				}

				if (UserModel.ANONYMOUS.equals(user)) {
					// server allows anonymous pushes, but anonymous patchset
					// contributions are prohibited by design
					sendRejection(cmd, "Sorry, anonymous patchset contributions are prohibited.");
					continue;
				}

				final Matcher m = NEW_PATCHSET.matcher(cmd.getRefName());
				if (m.matches()) {
					// prohibit pushing directly to a patchset ref
					long id = getTicketId(cmd.getRefName());
					sendError("You may not directly push directly to a patchset ref!");
					sendError("Instead, please push to one the following:");
					sendError(" - {0}{1,number,0}", Constants.R_FOR, id);
					sendError(" - {0}{1,number,0}", Constants.R_TICKET, id);
					sendRejection(cmd, "protected ref");
					continue;
				}

				if (hasRefNamespace(Constants.R_FOR)) {
					// the refs/for/ namespace exists and it must not
					LOGGER.error("{} already has refs in the {} namespace",
							repository.name, Constants.R_FOR);
					sendRejection(cmd, "Sorry, a repository administrator will have to remove the {} namespace", Constants.R_FOR);
					continue;
				}

				if (cmd.getNewId().equals(ObjectId.zeroId())) {
					// ref deletion request
					if (cmd.getRefName().startsWith(Constants.R_TICKET)) {
						if (user.canDeleteRef(repository)) {
							batch.addCommand(cmd);
						} else {
							sendRejection(cmd, "Sorry, you do not have permission to delete {}", cmd.getRefName());
						}
					} else {
						sendRejection(cmd, "Sorry, you can not delete {}", cmd.getRefName());
					}
					continue;
				}

				if (patchsetRefCmd != null) {
					sendRejection(cmd, "You may only push one patchset at a time.");
					continue;
				}

				LOGGER.info(MessageFormat.format("Verifying {0} push ref \"{1}\" received from {2}",
						repository.name, cmd.getRefName(), user.username));

				// responsible verification
				String responsible = PatchsetCommand.getSingleOption(cmd, PatchsetCommand.RESPONSIBLE);
				if (!StringUtils.isEmpty(responsible)) {
					UserModel assignee = gitblit.getUserModel(responsible);
					if (assignee == null) {
						// no account by this name
						sendRejection(cmd, "{0} can not be assigned any tickets because there is no user account by that name", responsible);
						continue;
					} else if (!assignee.canPush(repository)) {
						// account does not have RW permissions
						sendRejection(cmd, "{0} ({1}) can not be assigned any tickets because the user does not have RW permissions for {2}",
								assignee.getDisplayName(), assignee.username, repository.name);
						continue;
					}
				}

				// milestone verification
				String milestone = PatchsetCommand.getSingleOption(cmd, PatchsetCommand.MILESTONE);
				if (!StringUtils.isEmpty(milestone)) {
					TicketMilestone milestoneModel = ticketService.getMilestone(repository, milestone);
					if (milestoneModel == null) {
						// milestone does not exist
						sendRejection(cmd, "Sorry, \"{0}\" is not a valid milestone!", milestone);
						continue;
					}
				}

				// watcher verification
				List<String> watchers = PatchsetCommand.getOptions(cmd, PatchsetCommand.WATCH);
				if (!ArrayUtils.isEmpty(watchers)) {
					boolean verified = true;
					for (String watcher : watchers) {
						UserModel user = gitblit.getUserModel(watcher);
						if (user == null) {
							// watcher does not exist
							sendRejection(cmd, "Sorry, \"{0}\" is not a valid username for the watch list!", watcher);
							verified = false;
							break;
						}
					}
					if (!verified) {
						continue;
					}
				}

				patchsetRefCmd = cmd;
				patchsetCmd = preparePatchset(cmd);
				if (patchsetCmd != null) {
					batch.addCommand(patchsetCmd);
				}
				continue;
			}

			batch.addCommand(cmd);
		}

		if (!batch.getCommands().isEmpty()) {
			try {
				batch.execute(getRevWalk(), updating);
			} catch (IOException err) {
				for (ReceiveCommand cmd : toApply) {
					if (cmd.getResult() == Result.NOT_ATTEMPTED) {
						sendRejection(cmd, "lock error: {0}", err.getMessage());
						LOGGER.error(MessageFormat.format("failed to lock {0}:{1}",
								repository.name, cmd.getRefName()), err);
					}
				}
			}
		}

		//
		// set the results into the patchset ref receive command
		//
		if (patchsetRefCmd != null && patchsetCmd != null) {
			if (!patchsetCmd.getResult().equals(Result.OK)) {
				// patchset command failed!
				LOGGER.error(patchsetCmd.getType() + " " + patchsetCmd.getRefName()
						+ " " + patchsetCmd.getResult());
				patchsetRefCmd.setResult(patchsetCmd.getResult(), patchsetCmd.getMessage());
			} else {
				// all patchset commands were applied
				patchsetRefCmd.setResult(Result.OK);

				// update the ticket branch ref
				RefUpdate ru = updateRef(
						patchsetCmd.getTicketBranch(),
						patchsetCmd.getNewId(),
						patchsetCmd.getPatchsetType());
				updateReflog(ru);

				TicketModel ticket = processPatchset(patchsetCmd);
				if (ticket != null) {
					ticketNotifier.queueMailing(ticket);
				}
			}
		}

		//
		// if there are standard ref update receive commands that were
		// successfully processed, process referenced tickets, if any
		//
		List<ReceiveCommand> allUpdates = ReceiveCommand.filter(batch.getCommands(), Result.OK);
		List<ReceiveCommand> refUpdates = excludePatchsetCommands(allUpdates);
		List<ReceiveCommand> stdUpdates = excludeTicketCommands(refUpdates);
		if (!stdUpdates.isEmpty()) {
			int ticketsProcessed = 0;
			for (ReceiveCommand cmd : stdUpdates) {
				switch (cmd.getType()) {
				case CREATE:
				case UPDATE:
				case UPDATE_NONFASTFORWARD:
					if (cmd.getRefName().startsWith(Constants.R_HEADS)) {
						Collection<TicketModel> tickets = processMergedTickets(cmd);
						ticketsProcessed += tickets.size();
						for (TicketModel ticket : tickets) {
							ticketNotifier.queueMailing(ticket);
						}
					}
					break;
				default:
					break;
				}
			}

			if (ticketsProcessed == 1) {
				sendInfo("1 ticket updated");
			} else if (ticketsProcessed > 1) {
				sendInfo("{0} tickets updated", ticketsProcessed);
			}
		}

		// reset the ticket caches for the repository
		ticketService.resetCaches(repository);
	}

	/**
	 * Prepares a patchset command.
	 *
	 * @param cmd
	 * @return the patchset command
	 */
	private PatchsetCommand preparePatchset(ReceiveCommand cmd) {
		String branch = getIntegrationBranch(cmd.getRefName());
		long number = getTicketId(cmd.getRefName());

		TicketModel ticket = null;
		if (number > 0 && ticketService.hasTicket(repository, number)) {
			ticket = ticketService.getTicket(repository, number);
		}

		if (ticket == null) {
			if (number > 0) {
				// requested ticket does not exist
				sendError("Sorry, {0} does not have ticket {1,number,0}!", repository.name, number);
				sendRejection(cmd, "Invalid ticket number");
				return null;
			}
		} else {
			if (ticket.isMerged()) {
				// ticket already merged & resolved
				Change mergeChange = null;
				for (Change change : ticket.changes) {
					if (change.isMerge()) {
						mergeChange = change;
						break;
					}
				}
				if (mergeChange != null) {
					sendError("Sorry, {0} already merged {1} from ticket {2,number,0} to {3}!",
						mergeChange.author, mergeChange.patchset, number, ticket.mergeTo);
				}
				sendRejection(cmd, "Ticket {0,number,0} already resolved", number);
				return null;
			} else if (!StringUtils.isEmpty(ticket.mergeTo)) {
				// ticket specifies integration branch
				branch = ticket.mergeTo;
			}
		}

		final int shortCommitIdLen = settings.getInteger(Keys.web.shortCommitIdLength, 6);
		final String shortTipId = cmd.getNewId().getName().substring(0, shortCommitIdLen);
		final RevCommit tipCommit = JGitUtils.getCommit(getRepository(), cmd.getNewId().getName());
		final String forBranch = branch;
		RevCommit mergeBase = null;
		Ref forBranchRef = getAdvertisedRefs().get(Constants.R_HEADS + forBranch);
		if (forBranchRef == null || forBranchRef.getObjectId() == null) {
			// unknown integration branch
			sendError("Sorry, there is no integration branch named ''{0}''.", forBranch);
			sendRejection(cmd, "Invalid integration branch specified");
			return null;
		} else {
			// determine the merge base for the patchset on the integration branch
			String base = JGitUtils.getMergeBase(getRepository(), forBranchRef.getObjectId(), tipCommit.getId());
			if (StringUtils.isEmpty(base)) {
				sendError("");
				sendError("There is no common ancestry between {0} and {1}.", forBranch, shortTipId);
				sendError("Please reconsider your proposed integration branch, {0}.", forBranch);
				sendError("");
				sendRejection(cmd, "no merge base for patchset and {0}", forBranch);
				return null;
			}
			mergeBase = JGitUtils.getCommit(getRepository(), base);
		}

		// ensure that the patchset can be cleanly merged right now
		MergeStatus status = JGitUtils.canMerge(getRepository(), tipCommit.getName(), forBranch);
		switch (status) {
		case ALREADY_MERGED:
			sendError("");
			sendError("You have already merged this patchset.", forBranch);
			sendError("");
			sendRejection(cmd, "everything up-to-date");
			return null;
		case MERGEABLE:
			break;
		default:
			if (ticket == null || requireMergeablePatchset) {
				sendError("");
				sendError("Your patchset can not be cleanly merged into {0}.", forBranch);
				sendError("Please rebase your patchset and push again.");
				sendError("NOTE:", number);
				sendError("You should push your rebase to refs/for/{0,number,0}", number);
				sendError("");
				sendError("  git push origin HEAD:refs/for/{0,number,0}", number);
				sendError("");
				sendRejection(cmd, "patchset not mergeable");
				return null;
			}
		}

		// check to see if this commit is already linked to a ticket
		long id = identifyTicket(tipCommit, false);
		if (id > 0) {
			sendError("{0} has already been pushed to ticket {1,number,0}.", shortTipId, id);
			sendRejection(cmd, "everything up-to-date");
			return null;
		}

		PatchsetCommand psCmd;
		if (ticket == null) {
			/*
			 *  NEW TICKET
			 */
			Patchset patchset = newPatchset(null, mergeBase.getName(), tipCommit.getName());

			int minLength = 10;
			int maxLength = 100;
			String minTitle = MessageFormat.format("  minimum length of a title is {0} characters.", minLength);
			String maxTitle = MessageFormat.format("  maximum length of a title is {0} characters.", maxLength);

			if (patchset.commits > 1) {
				sendError("");
				sendError("You may not create a ''{0}'' branch proposal ticket from {1} commits!",
						forBranch, patchset.commits);
				sendError("");
				// display an ellipsized log of the commits being pushed
				RevWalk walk = getRevWalk();
				walk.reset();
				walk.sort(RevSort.TOPO);
				int boundary = 3;
				int count = 0;
				try {
					walk.markStart(tipCommit);
					walk.markUninteresting(mergeBase);

					for (;;) {

						RevCommit c = walk.next();
						if (c == null) {
							break;
						}

						if (count < boundary || count >= (patchset.commits - boundary)) {

							walk.parseBody(c);
							sendError("   {0}  {1}", c.getName().substring(0, shortCommitIdLen),
								StringUtils.trimString(c.getShortMessage(), 60));

						} else if (count == boundary) {

							sendError("   ... more commits ...");

						}

						count++;
					}

				} catch (IOException e) {
					// Should never happen, the core receive process would have
					// identified the missing object earlier before we got control.
					LOGGER.error("failed to get commit count", e);
				} finally {
					walk.close();
				}

				sendError("");
				sendError("Possible Solutions:");
				sendError("");
				int solution = 1;
				String forSpec = cmd.getRefName().substring(Constants.R_FOR.length());
				if (forSpec.equals("default") || forSpec.equals("new")) {
					try {
						// determine other possible integration targets
						List<String> bases = Lists.newArrayList();
						for (Ref ref : getRepository().getRefDatabase().getRefs(Constants.R_HEADS).values()) {
							if (!ref.getName().startsWith(Constants.R_TICKET)
									&& !ref.getName().equals(forBranchRef.getName())) {
								if (JGitUtils.isMergedInto(getRepository(), ref.getObjectId(), tipCommit)) {
									bases.add(Repository.shortenRefName(ref.getName()));
								}
							}
						}

						if (!bases.isEmpty()) {

							if (bases.size() == 1) {
								// suggest possible integration targets
								String base = bases.get(0);
								sendError("{0}. Propose this change for the ''{1}'' branch.", solution++, base);
								sendError("");
								sendError("   git push origin HEAD:refs/for/{0}", base);
								sendError("   pt propose {0}", base);
								sendError("");
							} else {
								// suggest possible integration targets
								sendError("{0}. Propose this change for a different branch.", solution++);
								sendError("");
								for (String base : bases) {
									sendError("   git push origin HEAD:refs/for/{0}", base);
									sendError("   pt propose {0}", base);
									sendError("");
								}
							}

						}
					} catch (IOException e) {
						LOGGER.error(null, e);
					}
				}
				sendError("{0}. Squash your changes into a single commit with a meaningful message.", solution++);
				sendError("");
				sendError("{0}. Open a ticket for your changes and then push your {1} commits to the ticket.",
						solution++, patchset.commits);
				sendError("");
				sendError("   git push origin HEAD:refs/for/{id}");
				sendError("   pt propose {id}");
				sendError("");
				sendRejection(cmd, "too many commits");
				return null;
			}

			// require a reasonable title/subject
			String title = tipCommit.getFullMessage().trim().split("\n")[0];
			if (title.length() < minLength) {
				// reject, title too short
				sendError("");
				sendError("Please supply a longer title in your commit message!");
				sendError("");
				sendError(minTitle);
				sendError(maxTitle);
				sendError("");
				sendRejection(cmd, "ticket title is too short [{0}/{1}]", title.length(), maxLength);
				return null;
			}
			if (title.length() > maxLength) {
				// reject, title too long
				sendError("");
				sendError("Please supply a more concise title in your commit message!");
				sendError("");
				sendError(minTitle);
				sendError(maxTitle);
				sendError("");
				sendRejection(cmd, "ticket title is too long [{0}/{1}]", title.length(), maxLength);
				return null;
			}

			// assign new id
			long ticketId = ticketService.assignNewId(repository);

			// create the patchset command
			psCmd = new PatchsetCommand(user.username, patchset);
			psCmd.newTicket(tipCommit, forBranch, ticketId, cmd.getRefName());
		} else {
			/*
			 *  EXISTING TICKET
			 */
			Patchset patchset = newPatchset(ticket, mergeBase.getName(), tipCommit.getName());
			psCmd = new PatchsetCommand(user.username, patchset);
			psCmd.updateTicket(tipCommit, forBranch, ticket, cmd.getRefName());
		}

		// confirm user can push the patchset
		boolean pushPermitted = ticket == null
				|| !ticket.hasPatchsets()
				|| ticket.isAuthor(user.username)
				|| ticket.isPatchsetAuthor(user.username)
				|| ticket.isResponsible(user.username)
				|| user.canPush(repository);

		switch (psCmd.getPatchsetType()) {
		case Proposal:
			// proposals (first patchset) are always acceptable
			break;
		case FastForward:
			// patchset updates must be permitted
			if (!pushPermitted) {
				// reject
				sendError("");
				sendError("To push a patchset to this ticket one of the following must be true:");
				sendError("  1. you created the ticket");
				sendError("  2. you created the first patchset");
				sendError("  3. you are specified as responsible for the ticket");
				sendError("  4. you have push (RW) permissions to {0}", repository.name);
				sendError("");
				sendRejection(cmd, "not permitted to push to ticket {0,number,0}", ticket.number);
				return null;
			}
			break;
		default:
			// non-fast-forward push
			if (!pushPermitted) {
				// reject
				sendRejection(cmd, "non-fast-forward ({0})", psCmd.getPatchsetType());
				return null;
			}
			break;
		}
		return psCmd;
	}

	/**
	 * Creates or updates an ticket with the specified patchset.
	 *
	 * @param cmd
	 * @return a ticket if the creation or update was successful
	 */
	private TicketModel processPatchset(PatchsetCommand cmd) {
		Change change = cmd.getChange();

		if (cmd.isNewTicket()) {
			// create the ticket object
			TicketModel ticket = ticketService.createTicket(repository, cmd.getTicketId(), change);
			if (ticket != null) {
				sendInfo("");
				sendHeader("#{0,number,0}: {1}", ticket.number, StringUtils.trimString(ticket.title, Constants.LEN_SHORTLOG));
				sendInfo("created proposal ticket from patchset");
				sendInfo(ticketService.getTicketUrl(ticket));
				sendInfo("");

				// log the new patch ref
				RefLogUtils.updateRefLog(user, getRepository(),
						Arrays.asList(new ReceiveCommand(cmd.getOldId(), cmd.getNewId(), cmd.getRefName())));

				// call any patchset hooks
				for (PatchsetHook hook : gitblit.getExtensions(PatchsetHook.class)) {
					try {
						hook.onNewPatchset(ticket);
					} catch (Exception e) {
						LOGGER.error("Failed to execute extension", e);
					}
				}

				return ticket;
			} else {
				sendError("FAILED to create ticket");
			}
		} else {
			// update an existing ticket
			TicketModel ticket = ticketService.updateTicket(repository, cmd.getTicketId(), change);
			if (ticket != null) {
				sendInfo("");
				sendHeader("#{0,number,0}: {1}", ticket.number, StringUtils.trimString(ticket.title, Constants.LEN_SHORTLOG));
				if (change.patchset.rev == 1) {
					// new patchset
					sendInfo("uploaded patchset {0} ({1})", change.patchset.number, change.patchset.type.toString());
				} else {
					// updated patchset
					sendInfo("added {0} {1} to patchset {2}",
							change.patchset.added,
							change.patchset.added == 1 ? "commit" : "commits",
							change.patchset.number);
				}
				sendInfo(ticketService.getTicketUrl(ticket));
				sendInfo("");

				// log the new patchset ref
				RefLogUtils.updateRefLog(user, getRepository(),
					Arrays.asList(new ReceiveCommand(cmd.getOldId(), cmd.getNewId(), cmd.getRefName())));

				// call any patchset hooks
				final boolean isNewPatchset = change.patchset.rev == 1;
				for (PatchsetHook hook : gitblit.getExtensions(PatchsetHook.class)) {
					try {
						if (isNewPatchset) {
							hook.onNewPatchset(ticket);
						} else {
							hook.onUpdatePatchset(ticket);
						}
					} catch (Exception e) {
						LOGGER.error("Failed to execute extension", e);
					}
				}

				// return the updated ticket
				return ticket;
			} else {
				sendError("FAILED to upload {0} for ticket {1,number,0}", change.patchset, cmd.getTicketId());
			}
		}

		return null;
	}

	/**
	 * Automatically closes open tickets that have been merged to their integration
	 * branch by a client.
	 *
	 * @param cmd
	 */
	private Collection<TicketModel> processMergedTickets(ReceiveCommand cmd) {
		Map<Long, TicketModel> mergedTickets = new LinkedHashMap<Long, TicketModel>();
		final RevWalk rw = getRevWalk();
		try {
			rw.reset();
			rw.markStart(rw.parseCommit(cmd.getNewId()));
			if (!ObjectId.zeroId().equals(cmd.getOldId())) {
				rw.markUninteresting(rw.parseCommit(cmd.getOldId()));
			}

			RevCommit c;
			while ((c = rw.next()) != null) {
				rw.parseBody(c);
				long ticketNumber = identifyTicket(c, true);
				if (ticketNumber == 0L || mergedTickets.containsKey(ticketNumber)) {
					continue;
				}

				TicketModel ticket = ticketService.getTicket(repository, ticketNumber);
				if (ticket == null) {
					continue;
				}
				String integrationBranch;
				if (StringUtils.isEmpty(ticket.mergeTo)) {
					// unspecified integration branch
					integrationBranch = null;
				} else {
					// specified integration branch
					integrationBranch = Constants.R_HEADS + ticket.mergeTo;
				}

				// ticket must be open and, if specified, the ref must match the integration branch
				if (ticket.isClosed() || (integrationBranch != null && !integrationBranch.equals(cmd.getRefName()))) {
					continue;
				}

				String baseRef = PatchsetCommand.getBasePatchsetBranch(ticket.number);
				boolean knownPatchset = false;
				Set<Ref> refs = getRepository().getAllRefsByPeeledObjectId().get(c.getId());
				if (refs != null) {
					for (Ref ref : refs) {
						if (ref.getName().startsWith(baseRef)) {
							knownPatchset = true;
							break;
						}
					}
				}

				String mergeSha = c.getName();
				String mergeTo = Repository.shortenRefName(cmd.getRefName());
				Change change;
				Patchset patchset;
				if (knownPatchset) {
					// identify merged patchset by the patchset tip
					patchset = null;
					for (Patchset ps : ticket.getPatchsets()) {
						if (ps.tip.equals(mergeSha)) {
							patchset = ps;
							break;
						}
					}

					if (patchset == null) {
						// should not happen - unless ticket has been hacked
						sendError("Failed to find the patchset for {0} in ticket {1,number,0}?!",
								mergeSha, ticket.number);
						continue;
					}

					// create a new change
					change = new Change(user.username);
				} else {
					// new patchset pushed by user
					String base = cmd.getOldId().getName();
					patchset = newPatchset(ticket, base, mergeSha);
					PatchsetCommand psCmd = new PatchsetCommand(user.username, patchset);
					psCmd.updateTicket(c, mergeTo, ticket, null);

					// create a ticket patchset ref
					updateRef(psCmd.getPatchsetBranch(), c.getId(), patchset.type);
					RefUpdate ru = updateRef(psCmd.getTicketBranch(), c.getId(), patchset.type);
					updateReflog(ru);

					// create a change from the patchset command
					change = psCmd.getChange();
				}

				// set the common change data about the merge
				change.setField(Field.status, Status.Merged);
				change.setField(Field.mergeSha, mergeSha);
				change.setField(Field.mergeTo, mergeTo);

				if (StringUtils.isEmpty(ticket.responsible)) {
					// unassigned tickets are assigned to the closer
					change.setField(Field.responsible, user.username);
				}

				ticket = ticketService.updateTicket(repository, ticket.number, change);
				if (ticket != null) {
					sendInfo("");
					sendHeader("#{0,number,0}: {1}", ticket.number, StringUtils.trimString(ticket.title, Constants.LEN_SHORTLOG));
					sendInfo("closed by push of {0} to {1}", patchset, mergeTo);
					sendInfo(ticketService.getTicketUrl(ticket));
					sendInfo("");
					mergedTickets.put(ticket.number, ticket);
				} else {
					String shortid = mergeSha.substring(0, settings.getInteger(Keys.web.shortCommitIdLength, 6));
					sendError("FAILED to close ticket {0,number,0} by push of {1}", ticketNumber, shortid);
				}
			}
		} catch (IOException e) {
			LOGGER.error("Can't scan for changes to close", e);
		} finally {
			rw.reset();
		}

		return mergedTickets.values();
	}

	/**
	 * Try to identify a ticket id from the commit.
	 *
	 * @param commit
	 * @param parseMessage
	 * @return a ticket id or 0
	 */
	private long identifyTicket(RevCommit commit, boolean parseMessage) {
		// try lookup by change ref
		Map<AnyObjectId, Set<Ref>> map = getRepository().getAllRefsByPeeledObjectId();
		Set<Ref> refs = map.get(commit.getId());
		if (!ArrayUtils.isEmpty(refs)) {
			for (Ref ref : refs) {
				long number = PatchsetCommand.getTicketNumber(ref.getName());
				if (number > 0) {
					return number;
				}
			}
		}

		if (parseMessage) {
			// parse commit message looking for fixes/closes #n
			String dx = "(?:fixes|closes)[\\s-]+#?(\\d+)";
			String x = settings.getString(Keys.tickets.closeOnPushCommitMessageRegex, dx);
			if (StringUtils.isEmpty(x)) {
				x = dx;
			}
			try {
				Pattern p = Pattern.compile(x, Pattern.CASE_INSENSITIVE);
				Matcher m = p.matcher(commit.getFullMessage());
				while (m.find()) {
					String val = m.group(1);
					return Long.parseLong(val);
				}
			} catch (Exception e) {
				LOGGER.error(String.format("Failed to parse \"%s\" in commit %s", x, commit.getName()), e);
			}
		}
		return 0L;
	}

	private int countCommits(String baseId, String tipId) {
		int count = 0;
		RevWalk walk = getRevWalk();
		walk.reset();
		walk.sort(RevSort.TOPO);
		walk.sort(RevSort.REVERSE, true);
		try {
			RevCommit tip = walk.parseCommit(getRepository().resolve(tipId));
			RevCommit base = walk.parseCommit(getRepository().resolve(baseId));
			walk.markStart(tip);
			walk.markUninteresting(base);
			for (;;) {
				RevCommit c = walk.next();
				if (c == null) {
					break;
				}
				count++;
			}
		} catch (IOException e) {
			// Should never happen, the core receive process would have
			// identified the missing object earlier before we got control.
			LOGGER.error("failed to get commit count", e);
			return 0;
		} finally {
			walk.close();
		}
		return count;
	}

	/**
	 * Creates a new patchset with metadata.
	 *
	 * @param ticket
	 * @param mergeBase
	 * @param tip
	 */
	private Patchset newPatchset(TicketModel ticket, String mergeBase, String tip) {
		int totalCommits = countCommits(mergeBase, tip);

		Patchset newPatchset = new Patchset();
		newPatchset.tip = tip;
		newPatchset.base = mergeBase;
		newPatchset.commits = totalCommits;

		Patchset currPatchset = ticket == null ? null : ticket.getCurrentPatchset();
		if (currPatchset == null) {
			/*
			 * PROPOSAL PATCHSET
			 * patchset 1, rev 1
			 */
			newPatchset.number = 1;
			newPatchset.rev = 1;
			newPatchset.type = PatchsetType.Proposal;

			// diffstat from merge base
			DiffStat diffStat = DiffUtils.getDiffStat(getRepository(), mergeBase, tip);
			newPatchset.insertions = diffStat.getInsertions();
			newPatchset.deletions = diffStat.getDeletions();
		} else {
			/*
			 * PATCHSET UPDATE
			 */
			int added = totalCommits - currPatchset.commits;
			boolean ff = JGitUtils.isMergedInto(getRepository(), currPatchset.tip, tip);
			boolean squash = added < 0;
			boolean rebase = !currPatchset.base.equals(mergeBase);

			// determine type, number and rev of the patchset
			if (ff) {
				/*
				 * FAST-FORWARD
				 * patchset number preserved, rev incremented
				 */

				boolean merged = JGitUtils.isMergedInto(getRepository(), currPatchset.tip, ticket.mergeTo);
				if (merged) {
					// current patchset was already merged
					// new patchset, mark as rebase
					newPatchset.type = PatchsetType.Rebase;
					newPatchset.number = currPatchset.number + 1;
					newPatchset.rev = 1;

					// diffstat from parent
					DiffStat diffStat = DiffUtils.getDiffStat(getRepository(), mergeBase, tip);
					newPatchset.insertions = diffStat.getInsertions();
					newPatchset.deletions = diffStat.getDeletions();
				} else {
					// FF update to patchset
					newPatchset.type = PatchsetType.FastForward;
					newPatchset.number = currPatchset.number;
					newPatchset.rev = currPatchset.rev + 1;
					newPatchset.parent = currPatchset.tip;

					// diffstat from parent
					DiffStat diffStat = DiffUtils.getDiffStat(getRepository(), currPatchset.tip, tip);
					newPatchset.insertions = diffStat.getInsertions();
					newPatchset.deletions = diffStat.getDeletions();
				}
			} else {
				/*
				 * NON-FAST-FORWARD
				 * new patchset, rev 1
				 */
				if (rebase && squash) {
					newPatchset.type = PatchsetType.Rebase_Squash;
					newPatchset.number = currPatchset.number + 1;
					newPatchset.rev = 1;
				} else if (squash) {
					newPatchset.type = PatchsetType.Squash;
					newPatchset.number = currPatchset.number + 1;
					newPatchset.rev = 1;
				} else if (rebase) {
					newPatchset.type = PatchsetType.Rebase;
					newPatchset.number = currPatchset.number + 1;
					newPatchset.rev = 1;
				} else {
					newPatchset.type = PatchsetType.Amend;
					newPatchset.number = currPatchset.number + 1;
					newPatchset.rev = 1;
				}

				// diffstat from merge base
				DiffStat diffStat = DiffUtils.getDiffStat(getRepository(), mergeBase, tip);
				newPatchset.insertions = diffStat.getInsertions();
				newPatchset.deletions = diffStat.getDeletions();
			}

			if (added > 0) {
				// ignore squash (negative add)
				newPatchset.added = added;
			}
		}

		return newPatchset;
	}

	private RefUpdate updateRef(String ref, ObjectId newId, PatchsetType type) {
		ObjectId ticketRefId = ObjectId.zeroId();
		try {
			ticketRefId = getRepository().resolve(ref);
		} catch (Exception e) {
			// ignore
		}

		try {
			RefUpdate ru = getRepository().updateRef(ref,  false);
			ru.setRefLogIdent(getRefLogIdent());
			switch (type) {
			case Amend:
			case Rebase:
			case Rebase_Squash:
			case Squash:
				ru.setForceUpdate(true);
				break;
			default:
				break;
			}

			ru.setExpectedOldObjectId(ticketRefId);
			ru.setNewObjectId(newId);
			RefUpdate.Result result = ru.update(getRevWalk());
			if (result == RefUpdate.Result.LOCK_FAILURE) {
				sendError("Failed to obtain lock when updating {0}:{1}", repository.name, ref);
				sendError("Perhaps an administrator should remove {0}/{1}.lock?", getRepository().getDirectory(), ref);
				return null;
			}
			return ru;
		} catch (IOException e) {
			LOGGER.error("failed to update ref " + ref, e);
			sendError("There was an error updating ref {0}:{1}", repository.name, ref);
		}
		return null;
	}

	private void updateReflog(RefUpdate ru) {
		if (ru == null) {
			return;
		}

		ReceiveCommand.Type type = null;
		switch (ru.getResult()) {
		case NEW:
			type = Type.CREATE;
			break;
		case FAST_FORWARD:
			type = Type.UPDATE;
			break;
		case FORCED:
			type = Type.UPDATE_NONFASTFORWARD;
			break;
		default:
			LOGGER.error(MessageFormat.format("unexpected ref update type {0} for {1}",
					ru.getResult(), ru.getName()));
			return;
		}
		ReceiveCommand cmd = new ReceiveCommand(ru.getOldObjectId(), ru.getNewObjectId(), ru.getName(), type);
		RefLogUtils.updateRefLog(user, getRepository(), Arrays.asList(cmd));
	}

	/**
	 * Merge the specified patchset to the integration branch.
	 *
	 * @param ticket
	 * @param patchset
	 * @return true, if successful
	 */
	public MergeStatus merge(TicketModel ticket) {
		PersonIdent committer = new PersonIdent(user.getDisplayName(), StringUtils.isEmpty(user.emailAddress) ? (user.username + "@gitblit") : user.emailAddress);
		Patchset patchset = ticket.getCurrentPatchset();
		String message = MessageFormat.format("Merged #{0,number,0} \"{1}\"", ticket.number, ticket.title);
		Ref oldRef = null;
		try {
			oldRef = getRepository().getRef(ticket.mergeTo);
		} catch (IOException e) {
			LOGGER.error("failed to get ref for " + ticket.mergeTo, e);
		}
		MergeResult mergeResult = JGitUtils.merge(
				getRepository(),
				patchset.tip,
				ticket.mergeTo,
				committer,
				message);

		if (StringUtils.isEmpty(mergeResult.sha)) {
			LOGGER.error("FAILED to merge {} to {} ({})", new Object [] { patchset, ticket.mergeTo, mergeResult.status.name() });
			return mergeResult.status;
		}
		Change change = new Change(user.username);
		change.setField(Field.status, Status.Merged);
		change.setField(Field.mergeSha, mergeResult.sha);
		change.setField(Field.mergeTo, ticket.mergeTo);

		if (StringUtils.isEmpty(ticket.responsible)) {
			// unassigned tickets are assigned to the closer
			change.setField(Field.responsible, user.username);
		}

		long ticketId = ticket.number;
		ticket = ticketService.updateTicket(repository, ticket.number, change);
		if (ticket != null) {
			ticketNotifier.queueMailing(ticket);

			if (oldRef != null) {
				ReceiveCommand cmd = new ReceiveCommand(oldRef.getObjectId(),
						ObjectId.fromString(mergeResult.sha), oldRef.getName());
				cmd.setResult(Result.OK);
				List<ReceiveCommand> commands = Arrays.asList(cmd);

				logRefChange(commands);
				updateIncrementalPushTags(commands);
				updateGitblitRefLog(commands);
			}

			// call patchset hooks
			for (PatchsetHook hook : gitblit.getExtensions(PatchsetHook.class)) {
				try {
					hook.onMergePatchset(ticket);
				} catch (Exception e) {
					LOGGER.error("Failed to execute extension", e);
				}
			}
			return mergeResult.status;
		} else {
			LOGGER.error("FAILED to resolve ticket {} by merge from web ui", ticketId);
		}
		return mergeResult.status;
	}

	public void sendAll() {
		ticketNotifier.sendAll();
	}
}
