#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)
{
	struct repo_config_values *cfg = repo_config_values(the_repository);

	if (!cfg->apply_sparse_checkout || !cfg->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)
{
	struct repo_config_values *cfg = repo_config_values(the_repository);

	if (!cfg->apply_sparse_checkout ||
	    cfg->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;
}
