/*
 * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>
 * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.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 static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import static org.eclipse.jgit.lib.FileMode.GITLINK;
import static org.eclipse.jgit.lib.FileMode.TYPE_GITLINK;
import static org.eclipse.jgit.lib.FileMode.TYPE_TREE;

import java.io.IOException;
import java.io.InputStream;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jgit.api.errors.FilterFailedException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.NoFilepatternException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuildIterator;
import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.NameConflictTreeWalk;
import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.IndexDiffFilter;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.treewalk.filter.TreeFilter;

/**
 * A class used to execute a {@code Add} command. It has setters for all
 * supported options and arguments of this command and a {@link #call()} method
 * to finally execute the command. Each instance of this class should only be
 * used for one invocation of the command (means: one call to {@link #call()})
 *
 * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-add.html"
 *      >Git documentation about Add</a>
 */
public class AddCommand extends GitCommand<DirCache> {

	private List<String> filepatterns;

	private WorkingTreeIterator workingTreeIterator;

	private boolean update = false;

	// This defaults to true because it's what JGit has been doing
	// traditionally. The C git default would be false.
	private boolean renormalize = true;

	/**
	 * Constructor for AddCommand
	 *
	 * @param repo
	 *            the {@link org.eclipse.jgit.lib.Repository}
	 */
	public AddCommand(Repository repo) {
		super(repo);
		filepatterns = new ArrayList<>();
	}

	/**
	 * Add a path to a file/directory whose content should be added.
	 * <p>
	 * A directory name (e.g. <code>dir</code> to add <code>dir/file1</code> and
	 * <code>dir/file2</code>) can also be given to add all files in the
	 * directory, recursively. Fileglobs (e.g. *.c) are not yet supported.
	 *
	 * @param filepattern
	 *            repository-relative path of file/directory to add (with
	 *            <code>/</code> as separator)
	 * @return {@code this}
	 */
	public AddCommand addFilepattern(String filepattern) {
		checkCallable();
		filepatterns.add(filepattern);
		return this;
	}

	/**
	 * Allow clients to provide their own implementation of a FileTreeIterator
	 *
	 * @param f
	 *            a {@link org.eclipse.jgit.treewalk.WorkingTreeIterator}
	 *            object.
	 * @return {@code this}
	 */
	public AddCommand setWorkingTreeIterator(WorkingTreeIterator f) {
		workingTreeIterator = f;
		return this;
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Executes the {@code Add} command. Each instance of this class should only
	 * be used for one invocation of the command. Don't call this method twice
	 * on an instance.
	 */
	@Override
	public DirCache call() throws GitAPIException, NoFilepatternException {

		if (filepatterns.isEmpty())
			throw new NoFilepatternException(JGitText.get().atLeastOnePatternIsRequired);
		checkCallable();
		DirCache dc = null;
		boolean addAll = filepatterns.contains("."); //$NON-NLS-1$

		try (ObjectInserter inserter = repo.newObjectInserter();
				NameConflictTreeWalk tw = new NameConflictTreeWalk(repo)) {
			tw.setOperationType(OperationType.CHECKIN_OP);
			dc = repo.lockDirCache();

			DirCacheBuilder builder = dc.builder();
			tw.addTree(new DirCacheBuildIterator(builder));
			if (workingTreeIterator == null)
				workingTreeIterator = new FileTreeIterator(repo);
			workingTreeIterator.setDirCacheIterator(tw, 0);
			tw.addTree(workingTreeIterator);
			TreeFilter pathFilter = null;
			if (!addAll) {
				pathFilter = PathFilterGroup.createFromStrings(filepatterns);
			}
			if (!renormalize) {
				if (pathFilter == null) {
					tw.setFilter(new IndexDiffFilter(0, 1));
				} else {
					tw.setFilter(AndTreeFilter.create(new IndexDiffFilter(0, 1),
							pathFilter));
				}
			} else if (pathFilter != null) {
				tw.setFilter(pathFilter);
			}

			byte[] lastAdded = null;

			while (tw.next()) {
				DirCacheIterator c = tw.getTree(0, DirCacheIterator.class);
				WorkingTreeIterator f = tw.getTree(1, WorkingTreeIterator.class);
				if (c == null && f != null && f.isEntryIgnored()) {
					// file is not in index but is ignored, do nothing
					continue;
				} else if (c == null && update) {
					// Only update of existing entries was requested.
					continue;
				}

				DirCacheEntry entry = c != null ? c.getDirCacheEntry() : null;
				if (entry != null && entry.getStage() > 0
						&& lastAdded != null
						&& lastAdded.length == tw.getPathLength()
						&& tw.isPathPrefix(lastAdded, lastAdded.length) == 0) {
					// In case of an existing merge conflict the
					// DirCacheBuildIterator iterates over all stages of
					// this path, we however want to add only one
					// new DirCacheEntry per path.
					continue;
				}

				if (tw.isSubtree() && !tw.isDirectoryFileConflict()) {
					tw.enterSubtree();
					continue;
				}

				if (f == null) { // working tree file does not exist
					if (entry != null
							&& (!update || GITLINK == entry.getFileMode())) {
						builder.add(entry);
					}
					continue;
				}

				if (entry != null && entry.isAssumeValid()) {
					// Index entry is marked assume valid. Even though
					// the user specified the file to be added JGit does
					// not consider the file for addition.
					builder.add(entry);
					continue;
				}

				if ((f.getEntryRawMode() == TYPE_TREE
						&& f.getIndexFileMode(c) != FileMode.GITLINK) ||
						(f.getEntryRawMode() == TYPE_GITLINK
								&& f.getIndexFileMode(c) == FileMode.TREE)) {
					// Index entry exists and is symlink, gitlink or file,
					// otherwise the tree would have been entered above.
					// Replace the index entry by diving into tree of files.
					tw.enterSubtree();
					continue;
				}

				byte[] path = tw.getRawPath();
				if (entry == null || entry.getStage() > 0) {
					entry = new DirCacheEntry(path);
				}
				FileMode mode = f.getIndexFileMode(c);
				entry.setFileMode(mode);

				if (GITLINK != mode) {
					entry.setLength(f.getEntryLength());
					entry.setLastModified(f.getEntryLastModifiedInstant());
					long len = f.getEntryContentLength();
					// We read and filter the content multiple times.
					// f.getEntryContentLength() reads and filters the input and
					// inserter.insert(...) does it again. That's because an
					// ObjectInserter needs to know the length before it starts
					// inserting. TODO: Fix this by using Buffers.
					try (InputStream in = f.openEntryStream()) {
						ObjectId id = inserter.insert(OBJ_BLOB, len, in);
						entry.setObjectId(id);
					}
				} else {
					entry.setLength(0);
					entry.setLastModified(Instant.ofEpochSecond(0));
					entry.setObjectId(f.getEntryObjectId());
				}
				builder.add(entry);
				lastAdded = path;
			}
			inserter.flush();
			builder.commit();
			setCallable(false);
		} catch (IOException e) {
			Throwable cause = e.getCause();
			if (cause != null && cause instanceof FilterFailedException)
				throw (FilterFailedException) cause;
			throw new JGitInternalException(
					JGitText.get().exceptionCaughtDuringExecutionOfAddCommand, e);
		} finally {
			if (dc != null)
				dc.unlock();
		}

		return dc;
	}

	/**
	 * Set whether to only match against already tracked files
	 *
	 * @param update
	 *            If set to true, the command only matches {@code filepattern}
	 *            against already tracked files in the index rather than the
	 *            working tree. That means that it will never stage new files,
	 *            but that it will stage modified new contents of tracked files
	 *            and that it will remove files from the index if the
	 *            corresponding files in the working tree have been removed. In
	 *            contrast to the git command line a {@code filepattern} must
	 *            exist also if update is set to true as there is no concept of
	 *            a working directory here.
	 * @return {@code this}
	 */
	public AddCommand setUpdate(boolean update) {
		this.update = update;
		return this;
	}

	/**
	 * Whether to only match against already tracked files
	 *
	 * @return whether to only match against already tracked files
	 */
	public boolean isUpdate() {
		return update;
	}

	/**
	 * Defines whether the command will renormalize by re-applying the "clean"
	 * process to tracked files.
	 * <p>
	 * This does not automatically call {@link #setUpdate(boolean)}.
	 * </p>
	 *
	 * @param renormalize
	 *            whether to renormalize tracked files
	 * @return {@code this}
	 * @since 6.6
	 */
	public AddCommand setRenormalize(boolean renormalize) {
		this.renormalize = renormalize;
		return this;
	}

	/**
	 * Tells whether the command will renormalize by re-applying the "clean"
	 * process to tracked files.
	 * <p>
	 * For legacy reasons, this is {@code true} by default.
	 * </p>
	 * <p>
	 * This setting is independent of {@link #isUpdate()}. In C git,
	 * command-line option --renormalize implies --update.
	 * </p>
	 *
	 * @return whether files will be renormalized
	 * @since 6.6
	 */
	public boolean isRenormalize() {
		return renormalize;
	}
}
