/*
 * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.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.api;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.errors.NotSupportedException;
import org.eclipse.jgit.errors.TooLargeObjectInPackException;
import org.eclipse.jgit.errors.TooLargePackException;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RefLeaseSpec;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.Transport;

/**
 * A class used to execute a {@code Push} command. It has setters for all
 * supported options and arguments of this command and a {@link #call()} method
 * to finally execute the command.
 *
 * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-push.html"
 *      >Git documentation about Push</a>
 */
public class PushCommand extends
		TransportCommand<PushCommand, Iterable<PushResult>> {

	private String remote = Constants.DEFAULT_REMOTE_NAME;

	private final List<RefSpec> refSpecs;

	private final Map<String, RefLeaseSpec> refLeaseSpecs;

	private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;

	private String receivePack = RemoteConfig.DEFAULT_RECEIVE_PACK;

	private boolean dryRun;
	private boolean atomic;
	private boolean force;
	private boolean thin = Transport.DEFAULT_PUSH_THIN;

	private OutputStream out;

	private List<String> pushOptions;

	/**
	 * <p>
	 * Constructor for PushCommand.
	 * </p>
	 *
	 * @param repo
	 *            the {@link org.eclipse.jgit.lib.Repository}
	 */
	protected PushCommand(Repository repo) {
		super(repo);
		refSpecs = new ArrayList<>(3);
		refLeaseSpecs = new HashMap<>();
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Execute the {@code push} command with all the options and parameters
	 * collected by the setter methods of this class. Each instance of this
	 * class should only be used for one invocation of the command (means: one
	 * call to {@link #call()})
	 */
	@Override
	public Iterable<PushResult> call() throws GitAPIException,
			InvalidRemoteException,
			org.eclipse.jgit.api.errors.TransportException {
		checkCallable();

		ArrayList<PushResult> pushResults = new ArrayList<>(3);

		try {
			if (refSpecs.isEmpty()) {
				RemoteConfig config = new RemoteConfig(repo.getConfig(),
						getRemote());
				refSpecs.addAll(config.getPushRefSpecs());
			}
			if (refSpecs.isEmpty()) {
				Ref head = repo.exactRef(Constants.HEAD);
				if (head != null && head.isSymbolic())
					refSpecs.add(new RefSpec(head.getLeaf().getName()));
			}

			if (force) {
				for (int i = 0; i < refSpecs.size(); i++)
					refSpecs.set(i, refSpecs.get(i).setForceUpdate(true));
			}

			final List<Transport> transports;
			transports = Transport.openAll(repo, remote, Transport.Operation.PUSH);
			for (final Transport transport : transports) {
				transport.setPushThin(thin);
				transport.setPushAtomic(atomic);
				if (receivePack != null)
					transport.setOptionReceivePack(receivePack);
				transport.setDryRun(dryRun);
				transport.setPushOptions(pushOptions);
				configure(transport);

				final Collection<RemoteRefUpdate> toPush = transport
						.findRemoteRefUpdatesFor(refSpecs, refLeaseSpecs);

				try {
					PushResult result = transport.push(monitor, toPush, out);
					pushResults.add(result);

				} catch (TooLargePackException e) {
					throw new org.eclipse.jgit.api.errors.TooLargePackException(
							e.getMessage(), e);
				} catch (TooLargeObjectInPackException e) {
					throw new org.eclipse.jgit.api.errors.TooLargeObjectInPackException(
							e.getMessage(), e);
				} catch (TransportException e) {
					throw new org.eclipse.jgit.api.errors.TransportException(
							e.getMessage(), e);
				} finally {
					transport.close();
				}
			}

		} catch (URISyntaxException e) {
			throw new InvalidRemoteException(MessageFormat.format(
					JGitText.get().invalidRemote, remote));
		} catch (TransportException e) {
			throw new org.eclipse.jgit.api.errors.TransportException(
					e.getMessage(), e);
		} catch (NotSupportedException e) {
			throw new JGitInternalException(
					JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
					e);
		} catch (IOException e) {
			throw new JGitInternalException(
					JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
					e);
		}

		return pushResults;
	}

	/**
	 * The remote (uri or name) used for the push operation. If no remote is
	 * set, the default value of <code>Constants.DEFAULT_REMOTE_NAME</code> will
	 * be used.
	 *
	 * @see Constants#DEFAULT_REMOTE_NAME
	 * @param remote
	 *            the remote name
	 * @return {@code this}
	 */
	public PushCommand setRemote(String remote) {
		checkCallable();
		this.remote = remote;
		return this;
	}

	/**
	 * Get remote name
	 *
	 * @return the remote used for the remote operation
	 */
	public String getRemote() {
		return remote;
	}

	/**
	 * The remote executable providing receive-pack service for pack transports.
	 * If no receive-pack is set, the default value of
	 * <code>RemoteConfig.DEFAULT_RECEIVE_PACK</code> will be used.
	 *
	 * @see RemoteConfig#DEFAULT_RECEIVE_PACK
	 * @param receivePack
	 *            name of the remote executable providing the receive-pack
	 *            service
	 * @return {@code this}
	 */
	public PushCommand setReceivePack(String receivePack) {
		checkCallable();
		this.receivePack = receivePack;
		return this;
	}

	/**
	 * Get the name of the remote executable providing the receive-pack service
	 *
	 * @return the receive-pack used for the remote operation
	 */
	public String getReceivePack() {
		return receivePack;
	}

	/**
	 * Get timeout used for push operation
	 *
	 * @return the timeout used for the push operation
	 */
	public int getTimeout() {
		return timeout;
	}

	/**
	 * Get the progress monitor
	 *
	 * @return the progress monitor for the push operation
	 */
	public ProgressMonitor getProgressMonitor() {
		return monitor;
	}

	/**
	 * The progress monitor associated with the push operation. By default, this
	 * is set to <code>NullProgressMonitor</code>
	 *
	 * @see NullProgressMonitor
	 * @param monitor
	 *            a {@link org.eclipse.jgit.lib.ProgressMonitor}
	 * @return {@code this}
	 */
	public PushCommand setProgressMonitor(ProgressMonitor monitor) {
		checkCallable();
		if (monitor == null) {
			monitor = NullProgressMonitor.INSTANCE;
		}
		this.monitor = monitor;
		return this;
	}

	/**
	 * Get the <code>RefLeaseSpec</code>s.
	 *
	 * @return the <code>RefLeaseSpec</code>s
	 * @since 4.7
	 */
	public List<RefLeaseSpec> getRefLeaseSpecs() {
		return new ArrayList<>(refLeaseSpecs.values());
	}

	/**
	 * The ref lease specs to be used in the push operation, for a
	 * force-with-lease push operation.
	 *
	 * @param specs
	 *            a {@link org.eclipse.jgit.transport.RefLeaseSpec} object.
	 * @return {@code this}
	 * @since 4.7
	 */
	public PushCommand setRefLeaseSpecs(RefLeaseSpec... specs) {
		return setRefLeaseSpecs(Arrays.asList(specs));
	}

	/**
	 * The ref lease specs to be used in the push operation, for a
	 * force-with-lease push operation.
	 *
	 * @param specs
	 *            list of {@code RefLeaseSpec}s
	 * @return {@code this}
	 * @since 4.7
	 */
	public PushCommand setRefLeaseSpecs(List<RefLeaseSpec> specs) {
		checkCallable();
		this.refLeaseSpecs.clear();
		for (RefLeaseSpec spec : specs) {
			refLeaseSpecs.put(spec.getRef(), spec);
		}
		return this;
	}

	/**
	 * Get {@code RefSpec}s.
	 *
	 * @return the ref specs
	 */
	public List<RefSpec> getRefSpecs() {
		return refSpecs;
	}

	/**
	 * The ref specs to be used in the push operation
	 *
	 * @param specs a {@link org.eclipse.jgit.transport.RefSpec} object.
	 * @return {@code this}
	 */
	public PushCommand setRefSpecs(RefSpec... specs) {
		checkCallable();
		this.refSpecs.clear();
		Collections.addAll(refSpecs, specs);
		return this;
	}

	/**
	 * The ref specs to be used in the push operation
	 *
	 * @param specs
	 *            list of {@link org.eclipse.jgit.transport.RefSpec}s
	 * @return {@code this}
	 */
	public PushCommand setRefSpecs(List<RefSpec> specs) {
		checkCallable();
		this.refSpecs.clear();
		this.refSpecs.addAll(specs);
		return this;
	}

	/**
	 * Push all branches under refs/heads/*.
	 *
	 * @return {code this}
	 */
	public PushCommand setPushAll() {
		refSpecs.add(Transport.REFSPEC_PUSH_ALL);
		return this;
	}

	/**
	 * Push all tags under refs/tags/*.
	 *
	 * @return {code this}
	 */
	public PushCommand setPushTags() {
		refSpecs.add(Transport.REFSPEC_TAGS);
		return this;
	}

	/**
	 * Add a reference to push.
	 *
	 * @param ref
	 *            the source reference. The remote name will match.
	 * @return {@code this}.
	 */
	public PushCommand add(Ref ref) {
		refSpecs.add(new RefSpec(ref.getLeaf().getName()));
		return this;
	}

	/**
	 * Add a reference to push.
	 *
	 * @param nameOrSpec
	 *            any reference name, or a reference specification.
	 * @return {@code this}.
	 * @throws JGitInternalException
	 *             the reference name cannot be resolved.
	 */
	public PushCommand add(String nameOrSpec) {
		if (0 <= nameOrSpec.indexOf(':')) {
			refSpecs.add(new RefSpec(nameOrSpec));
		} else {
			Ref src;
			try {
				src = repo.findRef(nameOrSpec);
			} catch (IOException e) {
				throw new JGitInternalException(
						JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
						e);
			}
			if (src != null)
				add(src);
		}
		return this;
	}

	/**
	 * Whether to run the push operation as a dry run
	 *
	 * @return the dry run preference for the push operation
	 */
	public boolean isDryRun() {
		return dryRun;
	}

	/**
	 * Sets whether the push operation should be a dry run
	 *
	 * @param dryRun a boolean.
	 * @return {@code this}
	 */
	public PushCommand setDryRun(boolean dryRun) {
		checkCallable();
		this.dryRun = dryRun;
		return this;
	}

	/**
	 * Get the thin-pack preference
	 *
	 * @return the thin-pack preference for push operation
	 */
	public boolean isThin() {
		return thin;
	}

	/**
	 * Set the thin-pack preference for push operation.
	 *
	 * Default setting is Transport.DEFAULT_PUSH_THIN
	 *
	 * @param thin
	 *            the thin-pack preference value
	 * @return {@code this}
	 */
	public PushCommand setThin(boolean thin) {
		checkCallable();
		this.thin = thin;
		return this;
	}

	/**
	 * Whether this push should be executed atomically (all references updated,
	 * or none)
	 *
	 * @return true if all-or-nothing behavior is requested.
	 * @since 4.2
	 */
	public boolean isAtomic() {
		return atomic;
	}

	/**
	 * Requests atomic push (all references updated, or no updates).
	 *
	 * Default setting is false.
	 *
	 * @param atomic
	 *            whether to run the push atomically
	 * @return {@code this}
	 * @since 4.2
	 */
	public PushCommand setAtomic(boolean atomic) {
		checkCallable();
		this.atomic = atomic;
		return this;
	}

	/**
	 * Whether to push forcefully
	 *
	 * @return the force preference for push operation
	 */
	public boolean isForce() {
		return force;
	}

	/**
	 * Sets the force preference for push operation.
	 *
	 * @param force
	 *            whether to push forcefully
	 * @return {@code this}
	 */
	public PushCommand setForce(boolean force) {
		checkCallable();
		this.force = force;
		return this;
	}

	/**
	 * Sets the output stream to write sideband messages to
	 *
	 * @param out
	 *            an {@link java.io.OutputStream}
	 * @return {@code this}
	 * @since 3.0
	 */
	public PushCommand setOutputStream(OutputStream out) {
		this.out = out;
		return this;
	}

	/**
	 * Get push options
	 *
	 * @return the option strings associated with the push operation
	 * @since 4.5
	 */
	public List<String> getPushOptions() {
		return pushOptions;
	}

	/**
	 * Set the option strings associated with the push operation.
	 *
	 * @param pushOptions
	 *            a {@link java.util.List} of push option strings
	 * @return {@code this}
	 * @since 4.5
	 */
	public PushCommand setPushOptions(List<String> pushOptions) {
		this.pushOptions = pushOptions;
		return this;
	}
}
