#define USE_THE_REPOSITORY_VARIABLE
#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "environment.h"
#include "ewah/ewok.h"
#include "gettext.h"
#include "name-hash.h"
#include "read-cache-ll.h"
#include "repository.h"
#include "sparse-index.h"
#include "tree.h"
#include "pathspec.h"
#include "trace2.h"
#include "cache-tree.h"
#include "config.h"
#include "dir.h"
#include "fsmonitor-ll.h"
#include "advice.h"

/**
 * This global is used by expand_index() to determine if we should give the
 * advice for advice.sparseIndexExpanded when expanding a sparse index to a full
 * one. However, this is sometimes done on purpose, such as in the sparse-checkout
 * builtin, even when index.sparse=false. This may be disabled in
 * convert_to_sparse() or by commands that know they will lead to a full
 * expansion, but this message is not actionable.
 */
int give_advice_on_expansion = 1;
#define ADVICE_MSG \
	"The sparse index is expanding to a full index, a slow operation.\n"   \
	"Your working directory likely has contents that are outside of\n"     \
	"your sparse-checkout patterns. Use 'git sparse-checkout list' to\n"   \
	"see your sparse-checkout definition and compare it to your working\n" \
	"directory contents. Cleaning up any merge conflicts or staged\n"      \
	"changes before running 'git sparse-checkout clean' or 'git\n"         \
	"sparse-checkout reapply' may assist in this cleanup."

struct modify_index_context {
	struct index_state *write;
	struct pattern_list *pl;
};

static struct cache_entry *construct_sparse_dir_entry(
				struct index_state *istate,
				const char *sparse_dir,
				struct cache_tree *tree)
{
	struct cache_entry *de;

	de = make_cache_entry(istate, S_IFDIR, &tree->oid, sparse_dir, 0, 0);

	de->ce_flags |= CE_SKIP_WORKTREE;
	return de;
}

/*
 * Returns the number of entries "inserted" into the index.
 */
static int convert_to_sparse_rec(struct index_state *istate,
				 int num_converted,
				 int start, int end,
				 const char *ct_path, size_t ct_pathlen,
				 struct cache_tree *ct)
{
	int i, can_convert = 1;
	int start_converted = num_converted;
	struct strbuf child_path = STRBUF_INIT;

	/*
	 * Is the current path outside of the sparse cone?
	 * Then check if the region can be replaced by a sparse
	 * directory entry (everything is sparse and merged).
	 */
	if (path_in_sparse_checkout(ct_path, istate))
		can_convert = 0;

	for (i = start; can_convert && i < end; i++) {
		struct cache_entry *ce = istate->cache[i];

		if (ce_stage(ce) ||
		    S_ISGITLINK(ce->ce_mode) ||
		    !(ce->ce_flags & CE_SKIP_WORKTREE))
			can_convert = 0;
	}

	if (can_convert) {
		struct cache_entry *se;
		se = construct_sparse_dir_entry(istate, ct_path, ct);

		istate->cache[num_converted++] = se;
		return 1;
	}

	for (i = start; i < end; ) {
		int count, span, pos = -1;
		const char *base, *slash;
		struct cache_entry *ce = istate->cache[i];

		/*
		 * Detect if this is a normal entry outside of any subtree
		 * entry.
		 */
		base = ce->name + ct_pathlen;
		slash = strchr(base, '/');

		if (slash)
			pos = cache_tree_subtree_pos(ct, base, slash - base);

		if (pos < 0) {
			istate->cache[num_converted++] = ce;
			i++;
			continue;
		}

		strbuf_setlen(&child_path, 0);
		strbuf_add(&child_path, ce->name, slash - ce->name + 1);

		span = ct->down[pos]->cache_tree->entry_count;
		count = convert_to_sparse_rec(istate,
					      num_converted, i, i + span,
					      child_path.buf, child_path.len,
					      ct->down[pos]->cache_tree);
		num_converted += count;
		i += span;
	}

	strbuf_release(&child_path);
	return num_converted - start_converted;
}

int set_sparse_index_config(struct repository *repo, int enable)
{
	int res = repo_config_set_worktree_gently(repo,
						  "index.sparse",
						  enable ? "true" : "false");
	prepare_repo_settings(repo);
	repo->settings.sparse_index = enable;
	return res;
}

static int index_has_unmerged_entries(struct index_state *istate)
{
	int i;
	for (i = 0; i < istate->cache_nr; i++) {
		if (ce_stage(istate->cache[i]))
			return 1;
	}

	return 0;
}

int is_sparse_index_allowed(struct index_state *istate, int flags)
{
	if (!core_apply_sparse_checkout || !core_sparse_checkout_cone)
		return 0;

	if (!(flags & SPARSE_INDEX_MEMORY_ONLY)) {
		int test_env;

		/*
		 * The sparse index is not (yet) integrated with a split index.
		 */
		if (istate->split_index || git_env_bool("GIT_TEST_SPLIT_INDEX", 0))
			return 0;
		/*
		 * The GIT_TEST_SPARSE_INDEX environment variable triggers the
		 * index.sparse config variable to be on.
		 */
		test_env = git_env_bool("GIT_TEST_SPARSE_INDEX", -1);
		if (test_env >= 0)
			set_sparse_index_config(istate->repo, test_env);

		/*
		 * Only convert to sparse if index.sparse is set.
		 */
		prepare_repo_settings(istate->repo);
		if (!istate->repo->settings.sparse_index)
			return 0;
	}

	if (init_sparse_checkout_patterns(istate))
		return 0;

	/*
	 * We need cone-mode patterns to use sparse-index. If a user edits
	 * their sparse-checkout file manually, then we can detect during
	 * parsing that they are not actually using cone-mode patterns and
	 * hence we need to abort this conversion _without error_. Warnings
	 * already exist in the pattern parsing to inform the user of their
	 * bad patterns.
	 */
	if (!istate->sparse_checkout_patterns->use_cone_patterns)
		return 0;

	return 1;
}

int convert_to_sparse(struct index_state *istate, int flags)
{
	/*
	 * If the index is already sparse, empty, or otherwise
	 * cannot be converted to sparse, do not convert.
	 */
	if (istate->sparse_index == INDEX_COLLAPSED || !istate->cache_nr ||
	    !is_sparse_index_allowed(istate, flags))
		return 0;

	/*
	 * If we are purposefully collapsing a full index, then don't give
	 * advice when it is expanded later.
	 */
	give_advice_on_expansion = 0;

	/*
	 * NEEDSWORK: If we have unmerged entries, then stay full.
	 * Unmerged entries prevent the cache-tree extension from working.
	 */
	if (index_has_unmerged_entries(istate))
		return 0;

	if (!cache_tree_fully_valid(istate->cache_tree)) {
		/* Clear and recompute the cache-tree */
		cache_tree_free(&istate->cache_tree);

		/*
		 * Silently return if there is a problem with the cache tree update,
		 * which might just be due to a conflict state in some entry.
		 *
		 * This might create new tree objects, so be sure to use
		 * WRITE_TREE_MISSING_OK.
		 */
		if (cache_tree_update(istate, WRITE_TREE_MISSING_OK))
			return 0;
	}

	remove_fsmonitor(istate);

	trace2_region_enter("index", "convert_to_sparse", istate->repo);
	istate->cache_nr = convert_to_sparse_rec(istate,
						 0, 0, istate->cache_nr,
						 "", 0, istate->cache_tree);

	/* Clear and recompute the cache-tree */
	cache_tree_free(&istate->cache_tree);
	cache_tree_update(istate, 0);

	istate->fsmonitor_has_run_once = 0;
	ewah_free(istate->fsmonitor_dirty);
	istate->fsmonitor_dirty = NULL;
	FREE_AND_NULL(istate->fsmonitor_last_update);

	istate->sparse_index = INDEX_COLLAPSED;
	trace2_region_leave("index", "convert_to_sparse", istate->repo);
	return 0;
}

static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
{
	ALLOC_GROW(istate->cache, nr + 1, istate->cache_alloc);

	istate->cache[nr] = ce;
	add_name_hash(istate, ce);
}

static int add_path_to_index(const struct object_id *oid,
			     struct strbuf *base, const char *path,
			     unsigned int mode, void *context)
{
	struct modify_index_context *ctx = (struct modify_index_context *)context;
	struct cache_entry *ce;
	size_t len = base->len;

	if (S_ISDIR(mode)) {
		int dtype;
		size_t baselen = base->len;
		if (!ctx->pl)
			return READ_TREE_RECURSIVE;

		/*
		 * Have we expanded to a point outside of the sparse-checkout?
		 *
		 * Artificially pad the path name with a slash "/" to
		 * indicate it as a directory, and add an arbitrary file
		 * name ("-") so we can consider base->buf as a file name
		 * to match against the cone-mode patterns.
		 *
		 * If we compared just "path", then we would expand more
		 * than we should. Since every file at root is always
		 * included, we would expand every directory at root at
		 * least one level deep instead of using sparse directory
		 * entries.
		 */
		strbuf_addstr(base, path);
		strbuf_add(base, "/-", 2);

		if (path_matches_pattern_list(base->buf, base->len,
					      NULL, &dtype,
					      ctx->pl, ctx->write)) {
			strbuf_setlen(base, baselen);
			return READ_TREE_RECURSIVE;
		}

		/*
		 * The path "{base}{path}/" is a sparse directory. Create the correct
		 * name for inserting the entry into the index.
		 */
		strbuf_setlen(base, base->len - 1);
	} else {
		strbuf_addstr(base, path);
	}

	ce = make_cache_entry(ctx->write, mode, oid, base->buf, 0, 0);
	ce->ce_flags |= CE_SKIP_WORKTREE | CE_EXTENDED;
	set_index_entry(ctx->write, ctx->write->cache_nr++, ce);

	strbuf_setlen(base, len);
	return 0;
}

void expand_index(struct index_state *istate, struct pattern_list *pl)
{
	int i;
	struct index_state *full;
	struct strbuf base = STRBUF_INIT;
	const char *tr_region;
	struct modify_index_context ctx;

	/*
	 * If the index is already full, then keep it full. We will convert
	 * it to a sparse index on write, if possible.
	 */
	if (istate->sparse_index == INDEX_EXPANDED)
		return;

	/*
	 * If our index is sparse, but our new pattern set does not use
	 * cone mode patterns, then we need to expand the index before we
	 * continue. A NULL pattern set indicates a full expansion to a
	 * full index.
	 */
	if (pl && !pl->use_cone_patterns) {
		pl = NULL;
	} else {
		/*
		 * We might contract file entries into sparse-directory
		 * entries, and for that we will need the cache tree to
		 * be recomputed.
		 */
		cache_tree_free(&istate->cache_tree);

		/*
		 * If there is a problem creating the cache tree, then we
		 * need to expand to a full index since we cannot satisfy
		 * the current request as a sparse index.
		 */
		if (cache_tree_update(istate, 0))
			pl = NULL;
	}

	if (!pl && give_advice_on_expansion) {
		give_advice_on_expansion = 0;
		advise_if_enabled(ADVICE_SPARSE_INDEX_EXPANDED,
				  _(ADVICE_MSG));
	}

	/*
	 * A NULL pattern set indicates we are expanding a full index, so
	 * we use a special region name that indicates the full expansion.
	 * This is used by test cases, but also helps to differentiate the
	 * two cases.
	 */
	tr_region = pl ? "expand_index" : "ensure_full_index";
	trace2_region_enter("index", tr_region, istate->repo);

	/* initialize basics of new index */
	full = xcalloc(1, sizeof(struct index_state));
	memcpy(full, istate, sizeof(struct index_state));

	/*
	 * This slightly-misnamed 'full' index might still be sparse if we
	 * are only modifying the list of sparse directories. This hinges
	 * on whether we have a non-NULL pattern list.
	 */
	full->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED;

	/* then change the necessary things */
	full->cache_alloc = (3 * istate->cache_alloc) / 2;
	full->cache_nr = 0;
	ALLOC_ARRAY(full->cache, full->cache_alloc);

	ctx.write = full;
	ctx.pl = pl;

	for (i = 0; i < istate->cache_nr; i++) {
		struct cache_entry *ce = istate->cache[i];
		struct tree *tree;
		struct pathspec ps;
		int dtype;

		if (!S_ISSPARSEDIR(ce->ce_mode)) {
			set_index_entry(full, full->cache_nr++, ce);
			continue;
		}

		/* We now have a sparse directory entry. Should we expand? */
		if (pl &&
		    path_matches_pattern_list(ce->name, ce->ce_namelen,
					      NULL, &dtype,
					      pl, istate) == NOT_MATCHED) {
			set_index_entry(full, full->cache_nr++, ce);
			continue;
		}

		if (!(ce->ce_flags & CE_SKIP_WORKTREE))
			warning(_("index entry is a directory, but not sparse (%08x)"),
				ce->ce_flags);

		/* recursively walk into cd->name */
		tree = lookup_tree(istate->repo, &ce->oid);

		memset(&ps, 0, sizeof(ps));
		ps.recursive = 1;
		ps.has_wildcard = 1;
		ps.max_depth = -1;

		strbuf_setlen(&base, 0);
		strbuf_add(&base, ce->name, strlen(ce->name));

		read_tree_at(istate->repo, tree, &base, 0, &ps,
			     add_path_to_index, &ctx);

		/* free directory entries. full entries are re-used */
		discard_cache_entry(ce);
	}

	/* Copy back into original index. */
	memcpy(&istate->name_hash, &full->name_hash, sizeof(full->name_hash));
	memcpy(&istate->dir_hash, &full->dir_hash, sizeof(full->dir_hash));
	istate->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED;
	free(istate->cache);
	istate->cache = full->cache;
	istate->cache_nr = full->cache_nr;
	istate->cache_alloc = full->cache_alloc;
	istate->fsmonitor_has_run_once = 0;
	ewah_free(istate->fsmonitor_dirty);
	istate->fsmonitor_dirty = NULL;
	FREE_AND_NULL(istate->fsmonitor_last_update);

	strbuf_release(&base);
	free(full);

	/* Clear and recompute the cache-tree */
	cache_tree_free(&istate->cache_tree);
	cache_tree_update(istate, 0);

	trace2_region_leave("index", tr_region, istate->repo);
}

void ensure_full_index(struct index_state *istate)
{
	if (!istate)
		BUG("ensure_full_index() must get an index!");
	expand_index(istate, NULL);
}

void ensure_correct_sparsity(struct index_state *istate)
{
	/*
	 * If the index can be sparse, make it sparse. Otherwise,
	 * ensure the index is full.
	 */
	if (is_sparse_index_allowed(istate, 0))
		convert_to_sparse(istate, 0);
	else
		ensure_full_index(istate);
}

struct path_found_data {
	/**
	 * The path stored in 'dir', if non-empty, corresponds to the most-
	 * recent path that we checked where:
	 *
	 *   1. The path should be a directory, according to the index.
	 *   2. The path does not exist.
	 *   3. The parent path _does_ exist. (This may be the root of the
	 *      working directory.)
	 */
	struct strbuf dir;
	size_t lstat_count;
};

#define PATH_FOUND_DATA_INIT { \
	.dir = STRBUF_INIT \
}

static void clear_path_found_data(struct path_found_data *data)
{
	strbuf_release(&data->dir);
}

/**
 * Return the length of the longest common substring that ends in a
 * slash ('/') to indicate the longest common parent directory. Returns
 * zero if no common directory exists.
 */
static size_t max_common_dir_prefix(const char *path1, const char *path2)
{
	size_t common_prefix = 0;
	for (size_t i = 0; path1[i] && path2[i]; i++) {
		if (path1[i] != path2[i])
			break;

		/*
		 * If they agree at a directory separator, then add one
		 * to make sure it is included in the common prefix string.
		 */
		if (path1[i] == '/')
			common_prefix = i + 1;
	}

	return common_prefix;
}

static int path_found(const char *path, struct path_found_data *data)
{
	struct stat st;
	size_t common_prefix;

	/*
	 * If data->dir is non-empty, then it contains a path that doesn't
	 * exist, including an ending slash ('/'). If it is a prefix of 'path',
	 * then we can return 0.
	 */
	if (data->dir.len && !memcmp(path, data->dir.buf, data->dir.len))
		return 0;

	/*
	 * Otherwise, we must check if the current path exists. If it does, then
	 * return 1. The cached directory will be skipped until we come across
	 * a missing path again.
	 */
	data->lstat_count++;
	if (!lstat(path, &st))
		return 1;

	/*
	 * At this point, we know that 'path' doesn't exist, and we know that
	 * the parent directory of 'data->dir' does exist. Let's set 'data->dir'
	 * to be the top-most non-existing directory of 'path'. If the first
	 * parent of 'path' exists, then we will act as though 'path'
	 * corresponds to a directory (by adding a slash).
	 */
	common_prefix = max_common_dir_prefix(path, data->dir.buf);

	/*
	 * At this point, 'path' and 'data->dir' have a common existing parent
	 * directory given by path[0..common_prefix] (which could have length 0).
	 * We "grow" the data->dir buffer by checking for existing directories
	 * along 'path'.
	 */

	strbuf_setlen(&data->dir, common_prefix);
	while (1) {
		/* Find the next directory in 'path'. */
		const char *rest = path + data->dir.len;
		const char *next_slash = strchr(rest, '/');

		/*
		 * If there are no more slashes, then 'path' doesn't contain a
		 * non-existent _parent_ directory. Set 'data->dir' to be equal
		 * to 'path' plus an additional slash, so it can be used for
		 * caching in the future. The filename of 'path' is considered
		 * a non-existent directory.
		 *
		 * Note: if "{path}/" exists as a directory, then it will never
		 * appear as a prefix of other callers to this method, assuming
		 * the context from the clear_skip_worktree... methods. If this
		 * method is reused, then this must be reconsidered.
		 */
		if (!next_slash) {
			strbuf_addstr(&data->dir, rest);
			strbuf_addch(&data->dir, '/');
			break;
		}

		/*
		 * Now that we have a slash, let's grow 'data->dir' to include
		 * this slash, then test if we should stop.
		 */
		strbuf_add(&data->dir, rest, next_slash - rest + 1);

		/* If the parent dir doesn't exist, then stop here. */
		data->lstat_count++;
		if (lstat(data->dir.buf, &st))
			return 0;
	}

	/*
	 * At this point, 'data->dir' is equal to 'path' plus a slash character,
	 * and the parent directory of 'path' definitely exists. Moreover, we
	 * know that 'path' doesn't exist, or we would have returned 1 earlier.
	 */
	return 0;
}

static int clear_skip_worktree_from_present_files_sparse(struct index_state *istate)
{
	struct path_found_data data = PATH_FOUND_DATA_INIT;

	int path_count = 0;
	int to_restart = 0;

	trace2_region_enter("index", "clear_skip_worktree_from_present_files_sparse",
			    istate->repo);
	for (int i = 0; i < istate->cache_nr; i++) {
		struct cache_entry *ce = istate->cache[i];

		if (ce_skip_worktree(ce)) {
			path_count++;
			if (path_found(ce->name, &data)) {
				if (S_ISSPARSEDIR(ce->ce_mode)) {
					to_restart = 1;
					break;
				}
				ce->ce_flags &= ~CE_SKIP_WORKTREE;
			}
		}
	}

	trace2_data_intmax("index", istate->repo,
			   "sparse_path_count", path_count);
	trace2_data_intmax("index", istate->repo,
			   "sparse_lstat_count", data.lstat_count);
	trace2_region_leave("index", "clear_skip_worktree_from_present_files_sparse",
			    istate->repo);
	clear_path_found_data(&data);
	return to_restart;
}

static void clear_skip_worktree_from_present_files_full(struct index_state *istate)
{
	struct path_found_data data = PATH_FOUND_DATA_INIT;

	int path_count = 0;

	trace2_region_enter("index", "clear_skip_worktree_from_present_files_full",
			    istate->repo);
	for (int i = 0; i < istate->cache_nr; i++) {
		struct cache_entry *ce = istate->cache[i];

		if (S_ISSPARSEDIR(ce->ce_mode))
			BUG("ensure-full-index did not fully flatten?");

		if (ce_skip_worktree(ce)) {
			path_count++;
			if (path_found(ce->name, &data))
				ce->ce_flags &= ~CE_SKIP_WORKTREE;
		}
	}

	trace2_data_intmax("index", istate->repo,
			   "full_path_count", path_count);
	trace2_data_intmax("index", istate->repo,
			   "full_lstat_count", data.lstat_count);
	trace2_region_leave("index", "clear_skip_worktree_from_present_files_full",
			    istate->repo);
	clear_path_found_data(&data);
}

void clear_skip_worktree_from_present_files(struct index_state *istate)
{
	if (!core_apply_sparse_checkout ||
	    sparse_expect_files_outside_of_patterns)
		return;

	if (clear_skip_worktree_from_present_files_sparse(istate)) {
		ensure_full_index(istate);
		clear_skip_worktree_from_present_files_full(istate);
	}
}

/*
 * This static global helps avoid infinite recursion between
 * expand_to_path() and index_file_exists().
 */
static int in_expand_to_path = 0;

void expand_to_path(struct index_state *istate,
		    const char *path, size_t pathlen, int icase)
{
	struct strbuf path_mutable = STRBUF_INIT;
	size_t substr_len;

	/* prevent extra recursion */
	if (in_expand_to_path)
		return;

	if (!istate->sparse_index)
		return;

	in_expand_to_path = 1;

	/*
	 * We only need to actually expand a region if the
	 * following are both true:
	 *
	 * 1. 'path' is not already in the index.
	 * 2. Some parent directory of 'path' is a sparse directory.
	 */

	if (index_file_exists(istate, path, pathlen, icase))
		goto cleanup;

	strbuf_add(&path_mutable, path, pathlen);
	strbuf_addch(&path_mutable, '/');

	/* Check the name hash for all parent directories */
	substr_len = 0;
	while (substr_len < pathlen) {
		char temp;
		char *replace = strchr(path_mutable.buf + substr_len, '/');

		if (!replace)
			break;

		/* replace the character _after_ the slash */
		replace++;
		temp = *replace;
		*replace = '\0';
		substr_len = replace - path_mutable.buf;
		if (index_file_exists(istate, path_mutable.buf,
				      substr_len, icase)) {
			/*
			 * We found a parent directory in the name-hash
			 * hashtable, because only sparse directory entries
			 * have a trailing '/' character.  Since "path" wasn't
			 * in the index, perhaps it exists within this
			 * sparse-directory.  Expand accordingly.
			 */
			ensure_full_index(istate);
			break;
		}

		*replace = temp;
	}

cleanup:
	strbuf_release(&path_mutable);
	in_expand_to_path = 0;
}
