/*
 * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
 * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.api;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Arrays;

import org.eclipse.jgit.api.errors.DetachedHeadException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRefNameException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefRename;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;

/**
 * Used to rename branches.
 *
 * @see <a
 *      href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html"
 *      >Git documentation about Branch</a>
 */
public class RenameBranchCommand extends GitCommand<Ref> {
	private String oldName;

	private String newName;

	/**
	 * <p>
	 * Constructor for RenameBranchCommand.
	 * </p>
	 *
	 * @param repo
	 *            the {@link org.eclipse.jgit.lib.Repository}
	 */
	protected RenameBranchCommand(Repository repo) {
		super(repo);
	}

	/** {@inheritDoc} */
	@Override
	public Ref call() throws GitAPIException, RefNotFoundException, InvalidRefNameException,
			RefAlreadyExistsException, DetachedHeadException {
		checkCallable();

		if (newName == null) {
			throw new InvalidRefNameException(MessageFormat.format(JGitText
					.get().branchNameInvalid, "<null>")); //$NON-NLS-1$
		}
		try {
			String fullOldName;
			String fullNewName;
			if (oldName != null) {
				// Don't just rely on findRef -- if there are local and remote
				// branches with the same name, and oldName is a short name, it
				// does not uniquely identify the ref and we might end up
				// renaming the wrong branch or finding a tag instead even
				// if a unique branch for the name exists!
				//
				// OldName may be a either a short or a full name.
				Ref ref = repo.exactRef(oldName);
				if (ref == null) {
					ref = repo.exactRef(Constants.R_HEADS + oldName);
					Ref ref2 = repo.exactRef(Constants.R_REMOTES + oldName);
					if (ref != null && ref2 != null) {
						throw new RefNotFoundException(MessageFormat.format(
								JGitText.get().renameBranchFailedAmbiguous,
								oldName, ref.getName(), ref2.getName()));
					} else if (ref == null) {
						if (ref2 != null) {
							ref = ref2;
						} else {
							throw new RefNotFoundException(MessageFormat.format(
									JGitText.get().refNotResolved, oldName));
						}
					}
				}
				fullOldName = ref.getName();
			} else {
				fullOldName = repo.getFullBranch();
				if (fullOldName == null) {
					throw new NoHeadException(
							JGitText.get().invalidRepositoryStateNoHead);
				}
				if (ObjectId.isId(fullOldName))
					throw new DetachedHeadException();
			}

			if (fullOldName.startsWith(Constants.R_REMOTES)) {
				fullNewName = Constants.R_REMOTES + newName;
			} else if (fullOldName.startsWith(Constants.R_HEADS)) {
				fullNewName = Constants.R_HEADS + newName;
			} else {
				throw new RefNotFoundException(MessageFormat.format(
						JGitText.get().renameBranchFailedNotABranch,
						fullOldName));
			}

			if (!Repository.isValidRefName(fullNewName)) {
				throw new InvalidRefNameException(MessageFormat.format(JGitText
						.get().branchNameInvalid, fullNewName));
			}
			if (repo.exactRef(fullNewName) != null) {
				throw new RefAlreadyExistsException(MessageFormat
						.format(JGitText.get().refAlreadyExists1, fullNewName));
			}
			RefRename rename = repo.renameRef(fullOldName, fullNewName);
			Result renameResult = rename.rename();

			setCallable(false);

			if (Result.RENAMED != renameResult) {
				throw new JGitInternalException(MessageFormat.format(JGitText
						.get().renameBranchUnexpectedResult, renameResult
						.name()));
			}
			if (fullNewName.startsWith(Constants.R_HEADS)) {
				String shortOldName = fullOldName.substring(Constants.R_HEADS
						.length());
				final StoredConfig repoConfig = repo.getConfig();
				// Copy all configuration values over to the new branch
				for (String name : repoConfig.getNames(
						ConfigConstants.CONFIG_BRANCH_SECTION, shortOldName)) {
					String[] values = repoConfig.getStringList(
							ConfigConstants.CONFIG_BRANCH_SECTION,
							shortOldName, name);
					if (values.length == 0) {
						continue;
					}
					// Keep any existing values already configured for the
					// new branch name
					String[] existing = repoConfig.getStringList(
							ConfigConstants.CONFIG_BRANCH_SECTION, newName,
							name);
					if (existing.length > 0) {
						String[] newValues = new String[values.length
								+ existing.length];
						System.arraycopy(existing, 0, newValues, 0,
								existing.length);
						System.arraycopy(values, 0, newValues, existing.length,
								values.length);
						values = newValues;
					}

					repoConfig.setStringList(
							ConfigConstants.CONFIG_BRANCH_SECTION, newName,
							name, Arrays.asList(values));
				}
				repoConfig.unsetSection(ConfigConstants.CONFIG_BRANCH_SECTION,
						shortOldName);
				repoConfig.save();
			}

			Ref resultRef = repo.exactRef(fullNewName);
			if (resultRef == null) {
				throw new JGitInternalException(
						JGitText.get().renameBranchFailedUnknownReason);
			}
			return resultRef;
		} catch (IOException ioe) {
			throw new JGitInternalException(ioe.getMessage(), ioe);
		}
	}

	/**
	 * Sets the new short name of the branch.
	 * <p>
	 * The full name is constructed using the prefix of the branch to be renamed
	 * defined by either {@link #setOldName(String)} or HEAD. If that old branch
	 * is a local branch, the renamed branch also will be, and if the old branch
	 * is a remote branch, so will be the renamed branch.
	 * </p>
	 *
	 * @param newName
	 *            the new name
	 * @return this instance
	 */
	public RenameBranchCommand setNewName(String newName) {
		checkCallable();
		this.newName = newName;
		return this;
	}

	/**
	 * Sets the old name of the branch.
	 * <p>
	 * {@code oldName} may be a short or a full name. Using a full name is
	 * recommended to unambiguously identify the branch to be renamed.
	 * </p>
	 *
	 * @param oldName
	 *            the name of the branch to rename; if not set, the currently
	 *            checked out branch (if any) will be renamed
	 * @return this instance
	 */
	public RenameBranchCommand setOldName(String oldName) {
		checkCallable();
		this.oldName = oldName;
		return this;
	}
}
