/*
 * Copyright (C) 2010, 2012 Christian Halstrick <christian.halstrick@sap.com> 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.pgm;

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

import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.pgm.opt.GpgSignHandler;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.util.RawParseUtils;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

@Command(common = true, usage = "usage_recordChangesToRepository")
class Commit extends TextBuiltin {
	// I don't support setting the committer, because also the native git
	// command doesn't allow this.

	@Option(name = "--author", metaVar = "metaVar_author", usage = "usage_CommitAuthor")
	private String author;

	@Option(name = "--message", aliases = { "-m" }, metaVar = "metaVar_message", usage = "usage_CommitMessage", required = true)
	private String message;

	@Option(name = "--only", aliases = { "-o" }, usage = "usage_CommitOnly")
	private boolean only;

	@Option(name = "--all", aliases = { "-a" }, usage = "usage_CommitAll")
	private boolean all;

	@Option(name = "--amend", usage = "usage_CommitAmend")
	private boolean amend;

	@Option(name = "--gpg-sign", aliases = { "-S" }, forbids = {
			"--no-gpg-sign" }, handler = GpgSignHandler.class)
	private String gpgSigningKey;

	@Option(name = "--no-gpg-sign", forbids = { "--gpg-sign" })
	private boolean noGpgSign;

	@Argument(metaVar = "metaVar_commitPaths", usage = "usage_CommitPaths")
	private List<String> paths = new ArrayList<>();

	/** {@inheritDoc} */
	@Override
	protected void run() {
		try (Git git = new Git(db)) {
			CommitCommand commitCmd = git.commit();
			if (author != null) {
				commitCmd.setAuthor(RawParseUtils.parsePersonIdent(author));
			}
			if (message != null) {
				commitCmd.setMessage(message);
			}
			if (noGpgSign) {
				commitCmd.setSign(Boolean.FALSE);
			} else if (gpgSigningKey != null) {
				commitCmd.setSign(Boolean.TRUE);
				if (!gpgSigningKey.equals(GpgSignHandler.DEFAULT)) {
					commitCmd.setSigningKey(gpgSigningKey);
				}
			}
			if (only && paths.isEmpty()) {
				throw die(CLIText.get().pathsRequired);
			}
			if (only && all) {
				throw die(CLIText.get().onlyOneCommitOptionAllowed);
			}
			if (!paths.isEmpty()) {
				for (String p : paths) {
					commitCmd.setOnly(p);
				}
			}
			commitCmd.setAmend(amend);
			commitCmd.setAll(all);
			Ref head = db.exactRef(Constants.HEAD);
			if (head == null) {
				throw die(CLIText.get().onBranchToBeBorn);
			}
			RevCommit commit;
			try {
				commit = commitCmd.call();
			} catch (JGitInternalException | GitAPIException e) {
				throw die(e.getMessage(), e);
			}

			String branchName;
			if (!head.isSymbolic()) {
				branchName = CLIText.get().branchDetachedHEAD;
			} else {
				branchName = head.getTarget().getName();
				if (branchName.startsWith(Constants.R_HEADS)) {
					branchName = branchName
							.substring(Constants.R_HEADS.length());
				}
			}
			outw.println('[' + branchName + ' ' + commit.name() + "] " //$NON-NLS-1$
					+ commit.getShortMessage());
		} catch (IOException e) {
			throw die(e.getMessage(), e);
		}
	}
}
