#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "add-interactive.h"
#include "color.h"
#include "config.h"
#include "diffcore.h"
#include "gettext.h"
#include "hash.h"
#include "hex.h"
#include "preload-index.h"
#include "read-cache-ll.h"
#include "repository.h"
#include "revision.h"
#include "refs.h"
#include "string-list.h"
#include "lockfile.h"
#include "dir.h"
#include "run-command.h"
#include "prompt.h"
#include "tree.h"

static void init_color(struct repository *r, enum git_colorbool use_color,
		       const char *section_and_slot, char *dst,
		       const char *default_color)
{
	char *key = xstrfmt("color.%s", section_and_slot);
	const char *value;

	if (!want_color(use_color))
		dst[0] = '\0';
	else if (repo_config_get_value(r, key, &value) ||
		 color_parse(value, dst))
		strlcpy(dst, default_color, COLOR_MAXLEN);

	free(key);
}

static enum git_colorbool check_color_config(struct repository *r, const char *var)
{
	const char *value;
	enum git_colorbool ret;

	if (repo_config_get_value(r, var, &value))
		ret = GIT_COLOR_UNKNOWN;
	else
		ret = git_config_colorbool(var, value);

	/*
	 * Do not rely on want_color() to fall back to color.ui for us. It uses
	 * the value parsed by git_color_config(), which may not have been
	 * called by the main command.
	 */
	if (ret == GIT_COLOR_UNKNOWN &&
	    !repo_config_get_value(r, "color.ui", &value))
		ret = git_config_colorbool("color.ui", value);

	return ret;
}

void init_add_i_state(struct add_i_state *s, struct repository *r,
		      struct add_p_opt *add_p_opt)
{
	s->r = r;
	s->context = -1;
	s->interhunkcontext = -1;

	s->use_color_interactive = check_color_config(r, "color.interactive");

	init_color(r, s->use_color_interactive, "interactive.header",
		   s->header_color, GIT_COLOR_BOLD);
	init_color(r, s->use_color_interactive, "interactive.help",
		   s->help_color, GIT_COLOR_BOLD_RED);
	init_color(r, s->use_color_interactive, "interactive.prompt",
		   s->prompt_color, GIT_COLOR_BOLD_BLUE);
	init_color(r, s->use_color_interactive, "interactive.error",
		   s->error_color, GIT_COLOR_BOLD_RED);
	strlcpy(s->reset_color_interactive,
		want_color(s->use_color_interactive) ? GIT_COLOR_RESET : "", COLOR_MAXLEN);

	s->use_color_diff = check_color_config(r, "color.diff");

	init_color(r, s->use_color_diff, "diff.frag", s->fraginfo_color,
		   diff_get_color(s->use_color_diff, DIFF_FRAGINFO));
	init_color(r, s->use_color_diff, "diff.context", s->context_color,
		   "fall back");
	if (!strcmp(s->context_color, "fall back"))
		init_color(r, s->use_color_diff, "diff.plain",
			   s->context_color,
			   diff_get_color(s->use_color_diff, DIFF_CONTEXT));
	init_color(r, s->use_color_diff, "diff.old", s->file_old_color,
		   diff_get_color(s->use_color_diff, DIFF_FILE_OLD));
	init_color(r, s->use_color_diff, "diff.new", s->file_new_color,
		   diff_get_color(s->use_color_diff, DIFF_FILE_NEW));
	strlcpy(s->reset_color_diff,
		want_color(s->use_color_diff) ? GIT_COLOR_RESET : "", COLOR_MAXLEN);

	FREE_AND_NULL(s->interactive_diff_filter);
	repo_config_get_string(r, "interactive.difffilter",
			       &s->interactive_diff_filter);

	FREE_AND_NULL(s->interactive_diff_algorithm);
	repo_config_get_string(r, "diff.algorithm",
			       &s->interactive_diff_algorithm);

	if (!repo_config_get_int(r, "diff.context", &s->context))
		if (s->context < 0)
			die(_("%s cannot be negative"), "diff.context");
	if (!repo_config_get_int(r, "diff.interHunkContext", &s->interhunkcontext))
		if (s->interhunkcontext < 0)
			die(_("%s cannot be negative"), "diff.interHunkContext");

	repo_config_get_bool(r, "interactive.singlekey", &s->use_single_key);
	if (s->use_single_key)
		setbuf(stdin, NULL);

	if (add_p_opt->context != -1) {
		if (add_p_opt->context < 0)
			die(_("%s cannot be negative"), "--unified");
		s->context = add_p_opt->context;
	}
	if (add_p_opt->interhunkcontext != -1) {
		if (add_p_opt->interhunkcontext < 0)
			die(_("%s cannot be negative"), "--inter-hunk-context");
		s->interhunkcontext = add_p_opt->interhunkcontext;
	}
}

void clear_add_i_state(struct add_i_state *s)
{
	FREE_AND_NULL(s->interactive_diff_filter);
	FREE_AND_NULL(s->interactive_diff_algorithm);
	memset(s, 0, sizeof(*s));
	s->use_color_interactive = GIT_COLOR_UNKNOWN;
	s->use_color_diff = GIT_COLOR_UNKNOWN;
}

/*
 * A "prefix item list" is a list of items that are identified by a string, and
 * a unique prefix (if any) is determined for each item.
 *
 * It is implemented in the form of a pair of `string_list`s, the first one
 * duplicating the strings, with the `util` field pointing at a structure whose
 * first field must be `size_t prefix_length`.
 *
 * That `prefix_length` field will be computed by `find_unique_prefixes()`; It
 * will be set to zero if no valid, unique prefix could be found.
 *
 * The second `string_list` is called `sorted` and does _not_ duplicate the
 * strings but simply reuses the first one's, with the `util` field pointing at
 * the `string_item_list` of the first `string_list`. It  will be populated and
 * sorted by `find_unique_prefixes()`.
 */
struct prefix_item_list {
	struct string_list items;
	struct string_list sorted;
	int *selected; /* for multi-selections */
	size_t min_length, max_length;
};
#define PREFIX_ITEM_LIST_INIT { \
	.items = STRING_LIST_INIT_DUP, \
	.sorted = STRING_LIST_INIT_NODUP, \
	.min_length = 1, \
	.max_length = 4, \
}

static void prefix_item_list_clear(struct prefix_item_list *list)
{
	string_list_clear(&list->items, 1);
	string_list_clear(&list->sorted, 0);
	FREE_AND_NULL(list->selected);
}

static void extend_prefix_length(struct string_list_item *p,
				 const char *other_string, size_t max_length)
{
	size_t *len = p->util;

	if (!*len || memcmp(p->string, other_string, *len))
		return;

	for (;;) {
		char c = p->string[*len];

		/*
		 * Is `p` a strict prefix of `other`? Or have we exhausted the
		 * maximal length of the prefix? Or is the current character a
		 * multi-byte UTF-8 one? If so, there is no valid, unique
		 * prefix.
		 */
		if (!c || ++*len > max_length || !isascii(c)) {
			*len = 0;
			break;
		}

		if (c != other_string[*len - 1])
			break;
	}
}

static void find_unique_prefixes(struct prefix_item_list *list)
{
	size_t i;

	if (list->sorted.nr == list->items.nr)
		return;

	string_list_clear(&list->sorted, 0);
	/* Avoid reallocating incrementally */
	list->sorted.items = xmalloc(st_mult(sizeof(*list->sorted.items),
					     list->items.nr));
	list->sorted.nr = list->sorted.alloc = list->items.nr;

	for (i = 0; i < list->items.nr; i++) {
		list->sorted.items[i].string = list->items.items[i].string;
		list->sorted.items[i].util = list->items.items + i;
	}

	string_list_sort(&list->sorted);

	for (i = 0; i < list->sorted.nr; i++) {
		struct string_list_item *sorted_item = list->sorted.items + i;
		struct string_list_item *item = sorted_item->util;
		size_t *len = item->util;

		*len = 0;
		while (*len < list->min_length) {
			char c = item->string[(*len)++];

			if (!c || !isascii(c)) {
				*len = 0;
				break;
			}
		}

		if (i > 0)
			extend_prefix_length(item, sorted_item[-1].string,
					     list->max_length);
		if (i + 1 < list->sorted.nr)
			extend_prefix_length(item, sorted_item[1].string,
					     list->max_length);
	}
}

static ssize_t find_unique(const char *string, struct prefix_item_list *list)
{
	int index = string_list_find_insert_index(&list->sorted, string, 1);
	struct string_list_item *item;

	if (list->items.nr != list->sorted.nr)
		BUG("prefix_item_list in inconsistent state (%"PRIuMAX
		    " vs %"PRIuMAX")",
		    (uintmax_t)list->items.nr, (uintmax_t)list->sorted.nr);

	if (index < 0)
		item = list->sorted.items[-1 - index].util;
	else if (index > 0 &&
		 starts_with(list->sorted.items[index - 1].string, string))
		return -1;
	else if (index + 1 < list->sorted.nr &&
		 starts_with(list->sorted.items[index + 1].string, string))
		return -1;
	else if (index < list->sorted.nr &&
		 starts_with(list->sorted.items[index].string, string))
		item = list->sorted.items[index].util;
	else
		return -1;
	return item - list->items.items;
}

struct list_options {
	int columns;
	const char *header;
	void (*print_item)(int i, int selected, struct string_list_item *item,
			   void *print_item_data);
	void *print_item_data;
};

static void list(struct add_i_state *s, struct string_list *list, int *selected,
		 struct list_options *opts)
{
	int i, last_lf = 0;

	if (!list->nr)
		return;

	if (opts->header)
		color_fprintf_ln(stdout, s->header_color,
				 "%s", opts->header);

	for (i = 0; i < list->nr; i++) {
		opts->print_item(i, selected ? selected[i] : 0, list->items + i,
				 opts->print_item_data);

		if ((opts->columns) && ((i + 1) % (opts->columns))) {
			putchar('\t');
			last_lf = 0;
		}
		else {
			putchar('\n');
			last_lf = 1;
		}
	}

	if (!last_lf)
		putchar('\n');
}
struct list_and_choose_options {
	struct list_options list_opts;

	const char *prompt;
	enum {
		SINGLETON = (1<<0),
		IMMEDIATE = (1<<1),
	} flags;
	void (*print_help)(struct add_i_state *s);
};

#define LIST_AND_CHOOSE_ERROR (-1)
#define LIST_AND_CHOOSE_QUIT  (-2)

/*
 * Returns the selected index in singleton mode, the number of selected items
 * otherwise.
 *
 * If an error occurred, returns `LIST_AND_CHOOSE_ERROR`. Upon EOF,
 * `LIST_AND_CHOOSE_QUIT` is returned.
 */
static ssize_t list_and_choose(struct add_i_state *s,
			       struct prefix_item_list *items,
			       struct list_and_choose_options *opts)
{
	int singleton = opts->flags & SINGLETON;
	int immediate = opts->flags & IMMEDIATE;

	struct strbuf input = STRBUF_INIT;
	ssize_t res = singleton ? LIST_AND_CHOOSE_ERROR : 0;

	if (!singleton) {
		free(items->selected);
		CALLOC_ARRAY(items->selected, items->items.nr);
	}

	if (singleton && !immediate)
		BUG("singleton requires immediate");

	find_unique_prefixes(items);

	for (;;) {
		char *p;

		strbuf_reset(&input);

		list(s, &items->items, items->selected, &opts->list_opts);

		color_fprintf(stdout, s->prompt_color, "%s", opts->prompt);
		fputs(singleton ? "> " : ">> ", stdout);
		fflush(stdout);

		if (git_read_line_interactively(&input) == EOF) {
			putchar('\n');
			if (immediate)
				res = LIST_AND_CHOOSE_QUIT;
			break;
		}

		if (!input.len)
			break;

		if (!strcmp(input.buf, "?")) {
			opts->print_help(s);
			continue;
		}

		p = input.buf;
		for (;;) {
			size_t sep = strcspn(p, " \t\r\n,");
			int choose = 1;
			/* `from` is inclusive, `to` is exclusive */
			ssize_t from = -1, to = -1;

			if (!sep) {
				if (!*p)
					break;
				p++;
				continue;
			}

			/* Input that begins with '-'; de-select */
			if (*p == '-') {
				choose = 0;
				p++;
				sep--;
			}

			if (sep == 1 && *p == '*') {
				from = 0;
				to = items->items.nr;
			} else if (isdigit(*p)) {
				char *endp;
				/*
				 * A range can be specified like 5-7 or 5-.
				 *
				 * Note: `from` is 0-based while the user input
				 * is 1-based, hence we have to decrement by
				 * one. We do not have to decrement `to` even
				 * if it is 0-based because it is an exclusive
				 * boundary.
				 */
				from = strtoul(p, &endp, 10) - 1;
				if (endp == p + sep)
					to = from + 1;
				else if (*endp == '-') {
					if (isdigit(*(++endp)))
						to = strtoul(endp, &endp, 10);
					else
						to = items->items.nr;
					/* extra characters after the range? */
					if (endp != p + sep)
						from = -1;
				}
			}

			if (p[sep])
				p[sep++] = '\0';
			if (from < 0) {
				from = find_unique(p, items);
				if (from >= 0)
					to = from + 1;
			}

			if (from < 0 || from >= items->items.nr ||
			    (singleton && from + 1 != to)) {
				color_fprintf_ln(stderr, s->error_color,
						 _("Huh (%s)?"), p);
				break;
			} else if (singleton) {
				res = from;
				break;
			}

			if (to > items->items.nr)
				to = items->items.nr;

			for (; from < to; from++)
				if (items->selected[from] != choose) {
					items->selected[from] = choose;
					res += choose ? +1 : -1;
				}

			p += sep;
		}

		if ((immediate && res != LIST_AND_CHOOSE_ERROR) ||
		    !strcmp(input.buf, "*"))
			break;
	}

	strbuf_release(&input);
	return res;
}

struct adddel {
	uintmax_t add, del;
	unsigned seen:1, unmerged:1, binary:1;
};

struct file_item {
	size_t prefix_length;
	struct adddel index, worktree;
};

static void add_file_item(struct string_list *files, const char *name)
{
	struct file_item *item = xcalloc(1, sizeof(*item));

	string_list_append(files, name)->util = item;
}

struct pathname_entry {
	struct hashmap_entry ent;
	const char *name;
	struct file_item *item;
};

static int pathname_entry_cmp(const void *cmp_data UNUSED,
			      const struct hashmap_entry *he1,
			      const struct hashmap_entry *he2,
			      const void *name)
{
	const struct pathname_entry *e1 =
		container_of(he1, const struct pathname_entry, ent);
	const struct pathname_entry *e2 =
		container_of(he2, const struct pathname_entry, ent);

	return strcmp(e1->name, name ? (const char *)name : e2->name);
}

struct collection_status {
	enum { FROM_WORKTREE = 0, FROM_INDEX = 1 } mode;

	const char *reference;

	unsigned skip_unseen:1;
	size_t unmerged_count, binary_count;
	struct string_list *files;
	struct hashmap file_map;
};

static void collect_changes_cb(struct diff_queue_struct *q,
			       struct diff_options *options,
			       void *data)
{
	struct collection_status *s = data;
	struct diffstat_t stat = { 0 };
	int i;

	if (!q->nr)
		return;

	compute_diffstat(options, &stat, q);

	for (i = 0; i < stat.nr; i++) {
		const char *name = stat.files[i]->name;
		int hash = strhash(name);
		struct pathname_entry *entry;
		struct file_item *file_item;
		struct adddel *adddel, *other_adddel;

		entry = hashmap_get_entry_from_hash(&s->file_map, hash, name,
						    struct pathname_entry, ent);
		if (!entry) {
			if (s->skip_unseen)
				continue;

			add_file_item(s->files, name);

			CALLOC_ARRAY(entry, 1);
			hashmap_entry_init(&entry->ent, hash);
			entry->name = s->files->items[s->files->nr - 1].string;
			entry->item = s->files->items[s->files->nr - 1].util;
			hashmap_add(&s->file_map, &entry->ent);
		}

		file_item = entry->item;
		adddel = s->mode == FROM_INDEX ?
			&file_item->index : &file_item->worktree;
		other_adddel = s->mode == FROM_INDEX ?
			&file_item->worktree : &file_item->index;
		adddel->seen = 1;
		adddel->add = stat.files[i]->added;
		adddel->del = stat.files[i]->deleted;
		if (stat.files[i]->is_binary) {
			if (!other_adddel->binary)
				s->binary_count++;
			adddel->binary = 1;
		}
		if (stat.files[i]->is_unmerged) {
			if (!other_adddel->unmerged)
				s->unmerged_count++;
			adddel->unmerged = 1;
		}
	}
	free_diffstat_info(&stat);
}

enum modified_files_filter {
	NO_FILTER = 0,
	WORKTREE_ONLY = 1,
	INDEX_ONLY = 2,
};

static int get_modified_files(struct repository *r,
			      enum modified_files_filter filter,
			      struct prefix_item_list *files,
			      const struct pathspec *ps,
			      size_t *unmerged_count,
			      size_t *binary_count)
{
	struct object_id head_oid;
	int is_initial = !refs_resolve_ref_unsafe(get_main_ref_store(r),
						  "HEAD", RESOLVE_REF_READING,
						  &head_oid, NULL);
	struct collection_status s = { 0 };
	int i;

	discard_index(r->index);
	if (repo_read_index_preload(r, ps, 0) < 0)
		return error(_("could not read index"));

	prefix_item_list_clear(files);
	s.files = &files->items;
	hashmap_init(&s.file_map, pathname_entry_cmp, NULL, 0);

	for (i = 0; i < 2; i++) {
		struct rev_info rev;
		struct setup_revision_opt opt = { 0 };

		if (filter == INDEX_ONLY)
			s.mode = (i == 0) ? FROM_INDEX : FROM_WORKTREE;
		else
			s.mode = (i == 0) ? FROM_WORKTREE : FROM_INDEX;
		s.skip_unseen = filter && i;

		opt.def = is_initial ?
			empty_tree_oid_hex(r->hash_algo) : oid_to_hex(&head_oid);

		repo_init_revisions(r, &rev, NULL);
		setup_revisions(0, NULL, &rev, &opt);

		rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
		rev.diffopt.format_callback = collect_changes_cb;
		rev.diffopt.format_callback_data = &s;

		if (ps)
			copy_pathspec(&rev.prune_data, ps);

		if (s.mode == FROM_INDEX)
			run_diff_index(&rev, DIFF_INDEX_CACHED);
		else {
			rev.diffopt.flags.ignore_dirty_submodules = 1;
			run_diff_files(&rev, 0);
		}

		release_revisions(&rev);
	}
	hashmap_clear_and_free(&s.file_map, struct pathname_entry, ent);
	if (unmerged_count)
		*unmerged_count = s.unmerged_count;
	if (binary_count)
		*binary_count = s.binary_count;

	/* While the diffs are ordered already, we ran *two* diffs... */
	string_list_sort(&files->items);

	return 0;
}

static void render_adddel(struct strbuf *buf,
				struct adddel *ad, const char *no_changes)
{
	if (ad->binary)
		strbuf_addstr(buf, _("binary"));
	else if (ad->seen)
		strbuf_addf(buf, "+%"PRIuMAX"/-%"PRIuMAX,
			    (uintmax_t)ad->add, (uintmax_t)ad->del);
	else
		strbuf_addstr(buf, no_changes);
}

/* filters out prefixes which have special meaning to list_and_choose() */
static int is_valid_prefix(const char *prefix, size_t prefix_len)
{
	return prefix_len && prefix &&
		/*
		 * We expect `prefix` to be NUL terminated, therefore this
		 * `strcspn()` call is okay, even if it might do much more
		 * work than strictly necessary.
		 */
		strcspn(prefix, " \t\r\n,") >= prefix_len &&	/* separators */
		*prefix != '-' &&				/* deselection */
		!isdigit(*prefix) &&				/* selection */
		(prefix_len != 1 ||
		 (*prefix != '*' &&				/* "all" wildcard */
		  *prefix != '?'));				/* prompt help */
}

struct print_file_item_data {
	const char *modified_fmt, *color, *reset;
	struct strbuf buf, name, index, worktree;
	unsigned only_names:1;
};

static void print_file_item(int i, int selected, struct string_list_item *item,
			    void *print_file_item_data)
{
	struct file_item *c = item->util;
	struct print_file_item_data *d = print_file_item_data;
	const char *highlighted = NULL;

	strbuf_reset(&d->index);
	strbuf_reset(&d->worktree);
	strbuf_reset(&d->buf);

	/* Format the item with the prefix highlighted. */
	if (c->prefix_length > 0 &&
	    is_valid_prefix(item->string, c->prefix_length)) {
		strbuf_reset(&d->name);
		strbuf_addf(&d->name, "%s%.*s%s%s", d->color,
			    (int)c->prefix_length, item->string, d->reset,
			    item->string + c->prefix_length);
		highlighted = d->name.buf;
	}

	if (d->only_names) {
		printf("%c%2d: %s", selected ? '*' : ' ', i + 1,
		       highlighted ? highlighted : item->string);
		return;
	}

	render_adddel(&d->worktree, &c->worktree, _("nothing"));
	render_adddel(&d->index, &c->index, _("unchanged"));

	strbuf_addf(&d->buf, d->modified_fmt, d->index.buf, d->worktree.buf,
		    highlighted ? highlighted : item->string);

	printf("%c%2d: %s", selected ? '*' : ' ', i + 1, d->buf.buf);
}

static int run_status(struct add_i_state *s, const struct pathspec *ps,
		      struct prefix_item_list *files,
		      struct list_and_choose_options *opts)
{
	if (get_modified_files(s->r, NO_FILTER, files, ps, NULL, NULL) < 0)
		return -1;

	list(s, &files->items, NULL, &opts->list_opts);
	putchar('\n');

	return 0;
}

static int run_update(struct add_i_state *s, const struct pathspec *ps,
		      struct prefix_item_list *files,
		      struct list_and_choose_options *opts)
{
	int res = 0, fd;
	size_t count, i;
	struct lock_file index_lock;

	if (get_modified_files(s->r, WORKTREE_ONLY, files, ps, NULL, NULL) < 0)
		return -1;

	if (!files->items.nr) {
		putchar('\n');
		return 0;
	}

	opts->prompt = N_("Update");
	count = list_and_choose(s, files, opts);
	if (count <= 0) {
		putchar('\n');
		return 0;
	}

	fd = repo_hold_locked_index(s->r, &index_lock, LOCK_REPORT_ON_ERROR);
	if (fd < 0) {
		putchar('\n');
		return -1;
	}

	for (i = 0; i < files->items.nr; i++) {
		const char *name = files->items.items[i].string;
		struct stat st;

		if (!files->selected[i])
			continue;
		if (lstat(name, &st) && is_missing_file_error(errno)) {
			if (remove_file_from_index(s->r->index, name) < 0) {
				res = error(_("could not stage '%s'"), name);
				break;
			}
		} else if (add_file_to_index(s->r->index, name, 0) < 0) {
			res = error(_("could not stage '%s'"), name);
			break;
		}
	}

	if (!res && write_locked_index(s->r->index, &index_lock, COMMIT_LOCK) < 0)
		res = error(_("could not write index"));

	if (!res)
		printf(Q_("updated %d path\n",
			  "updated %d paths\n", count), (int)count);

	putchar('\n');
	return res;
}

static void revert_from_diff(struct diff_queue_struct *q,
			     struct diff_options *opt, void *data UNUSED)
{
	int i, add_flags = ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE;

	for (i = 0; i < q->nr; i++) {
		struct diff_filespec *one = q->queue[i]->one;
		struct cache_entry *ce;

		if (!(one->mode && !is_null_oid(&one->oid))) {
			remove_file_from_index(opt->repo->index, one->path);
			printf(_("note: %s is untracked now.\n"), one->path);
		} else {
			ce = make_cache_entry(opt->repo->index, one->mode,
					      &one->oid, one->path, 0, 0);
			if (!ce)
				die(_("make_cache_entry failed for path '%s'"),
				    one->path);
			add_index_entry(opt->repo->index, ce, add_flags);
		}
	}
}

static int run_revert(struct add_i_state *s, const struct pathspec *ps,
		      struct prefix_item_list *files,
		      struct list_and_choose_options *opts)
{
	int res = 0, fd;
	size_t count, i, j;

	struct object_id oid;
	int is_initial = !refs_resolve_ref_unsafe(get_main_ref_store(s->r),
						  "HEAD", RESOLVE_REF_READING,
						  &oid,
						  NULL);
	struct lock_file index_lock;
	const char **paths;
	struct tree *tree;
	struct diff_options diffopt = { NULL };

	if (get_modified_files(s->r, INDEX_ONLY, files, ps, NULL, NULL) < 0)
		return -1;

	if (!files->items.nr) {
		putchar('\n');
		return 0;
	}

	opts->prompt = N_("Revert");
	count = list_and_choose(s, files, opts);
	if (count <= 0)
		goto finish_revert;

	fd = repo_hold_locked_index(s->r, &index_lock, LOCK_REPORT_ON_ERROR);
	if (fd < 0) {
		res = -1;
		goto finish_revert;
	}

	if (is_initial)
		oidcpy(&oid, s->r->hash_algo->empty_tree);
	else {
		tree = parse_tree_indirect(&oid);
		if (!tree) {
			res = error(_("Could not parse HEAD^{tree}"));
			goto finish_revert;
		}
		oidcpy(&oid, &tree->object.oid);
	}

	ALLOC_ARRAY(paths, count + 1);
	for (i = j = 0; i < files->items.nr; i++)
		if (files->selected[i])
			paths[j++] = files->items.items[i].string;
	paths[j] = NULL;

	parse_pathspec(&diffopt.pathspec, 0,
		       PATHSPEC_PREFER_FULL | PATHSPEC_LITERAL_PATH,
		       NULL, paths);

	diffopt.output_format = DIFF_FORMAT_CALLBACK;
	diffopt.format_callback = revert_from_diff;
	diffopt.flags.override_submodule_config = 1;
	diffopt.repo = s->r;

	if (do_diff_cache(&oid, &diffopt)) {
		diff_free(&diffopt);
		res = -1;
	} else {
		diffcore_std(&diffopt);
		diff_flush(&diffopt);
	}
	free(paths);

	if (!res && write_locked_index(s->r->index, &index_lock,
				       COMMIT_LOCK) < 0)
		res = -1;
	else
		res = repo_refresh_and_write_index(s->r, REFRESH_QUIET, 0, 1,
						   NULL, NULL, NULL);

	if (!res)
		printf(Q_("reverted %d path\n",
			  "reverted %d paths\n", count), (int)count);

finish_revert:
	putchar('\n');
	return res;
}

static int get_untracked_files(struct repository *r,
			       struct prefix_item_list *files,
			       const struct pathspec *ps)
{
	struct dir_struct dir = { 0 };
	size_t i;
	struct strbuf buf = STRBUF_INIT;

	if (repo_read_index(r) < 0)
		return error(_("could not read index"));

	prefix_item_list_clear(files);
	setup_standard_excludes(&dir);
	add_pattern_list(&dir, EXC_CMDL, "--exclude option");
	fill_directory(&dir, r->index, ps);

	for (i = 0; i < dir.nr; i++) {
		struct dir_entry *ent = dir.entries[i];

		if (index_name_is_other(r->index, ent->name, ent->len)) {
			strbuf_reset(&buf);
			strbuf_add(&buf, ent->name, ent->len);
			add_file_item(&files->items, buf.buf);
		}
	}

	strbuf_release(&buf);
	dir_clear(&dir);
	return 0;
}

static int run_add_untracked(struct add_i_state *s, const struct pathspec *ps,
		      struct prefix_item_list *files,
		      struct list_and_choose_options *opts)
{
	struct print_file_item_data *d = opts->list_opts.print_item_data;
	int res = 0, fd;
	size_t count, i;
	struct lock_file index_lock;

	if (get_untracked_files(s->r, files, ps) < 0)
		return -1;

	if (!files->items.nr) {
		printf(_("No untracked files.\n"));
		goto finish_add_untracked;
	}

	opts->prompt = N_("Add untracked");
	d->only_names = 1;
	count = list_and_choose(s, files, opts);
	d->only_names = 0;
	if (count <= 0)
		goto finish_add_untracked;

	fd = repo_hold_locked_index(s->r, &index_lock, LOCK_REPORT_ON_ERROR);
	if (fd < 0) {
		res = -1;
		goto finish_add_untracked;
	}

	for (i = 0; i < files->items.nr; i++) {
		const char *name = files->items.items[i].string;
		if (files->selected[i] &&
		    add_file_to_index(s->r->index, name, 0) < 0) {
			res = error(_("could not stage '%s'"), name);
			break;
		}
	}

	if (!res &&
	    write_locked_index(s->r->index, &index_lock, COMMIT_LOCK) < 0)
		res = error(_("could not write index"));

	if (!res)
		printf(Q_("added %d path\n",
			  "added %d paths\n", count), (int)count);

finish_add_untracked:
	putchar('\n');
	return res;
}

static int run_patch(struct add_i_state *s, const struct pathspec *ps,
		     struct prefix_item_list *files,
		     struct list_and_choose_options *opts)
{
	int res = 0;
	ssize_t count, i, j;
	size_t unmerged_count = 0, binary_count = 0;

	if (get_modified_files(s->r, WORKTREE_ONLY, files, ps,
			       &unmerged_count, &binary_count) < 0)
		return -1;

	if (unmerged_count || binary_count) {
		for (i = j = 0; i < files->items.nr; i++) {
			struct file_item *item = files->items.items[i].util;

			if (item->index.binary || item->worktree.binary) {
				free(item);
				free(files->items.items[i].string);
			} else if (item->index.unmerged ||
				 item->worktree.unmerged) {
				color_fprintf_ln(stderr, s->error_color,
						 _("ignoring unmerged: %s"),
						 files->items.items[i].string);
				free(item);
				free(files->items.items[i].string);
			} else
				files->items.items[j++] = files->items.items[i];
		}
		files->items.nr = j;
	}

	if (!files->items.nr) {
		if (binary_count)
			fprintf(stderr, _("Only binary files changed.\n"));
		else
			fprintf(stderr, _("No changes.\n"));
		return 0;
	}

	opts->prompt = N_("Patch update");
	count = list_and_choose(s, files, opts);
	if (count > 0) {
		struct add_p_opt add_p_opt = {
			.context = s->context,
			.interhunkcontext = s->interhunkcontext,
		};
		struct strvec args = STRVEC_INIT;
		struct pathspec ps_selected = { 0 };

		for (i = 0; i < files->items.nr; i++)
			if (files->selected[i])
				strvec_push(&args,
					    files->items.items[i].string);
		parse_pathspec(&ps_selected,
			       PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
			       PATHSPEC_LITERAL_PATH, "", args.v);
		res = run_add_p(s->r, ADD_P_ADD, &add_p_opt, NULL, &ps_selected);
		strvec_clear(&args);
		clear_pathspec(&ps_selected);
	}

	return res;
}

static int run_diff(struct add_i_state *s, const struct pathspec *ps,
		    struct prefix_item_list *files,
		    struct list_and_choose_options *opts)
{
	int res = 0;
	ssize_t count, i;

	struct object_id oid;
	int is_initial = !refs_resolve_ref_unsafe(get_main_ref_store(s->r),
						  "HEAD", RESOLVE_REF_READING,
						  &oid,
						  NULL);
	if (get_modified_files(s->r, INDEX_ONLY, files, ps, NULL, NULL) < 0)
		return -1;

	if (!files->items.nr) {
		putchar('\n');
		return 0;
	}

	opts->prompt = N_("Review diff");
	opts->flags = IMMEDIATE;
	count = list_and_choose(s, files, opts);
	opts->flags = 0;
	if (count > 0) {
		struct child_process cmd = CHILD_PROCESS_INIT;

		strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached", NULL);
		if (s->context != -1)
			strvec_pushf(&cmd.args, "--unified=%i", s->context);
		if (s->interhunkcontext != -1)
			strvec_pushf(&cmd.args, "--inter-hunk-context=%i", s->interhunkcontext);
		strvec_pushl(&cmd.args, oid_to_hex(!is_initial ? &oid :
			     s->r->hash_algo->empty_tree), "--", NULL);
		for (i = 0; i < files->items.nr; i++)
			if (files->selected[i])
				strvec_push(&cmd.args,
					    files->items.items[i].string);
		res = run_command(&cmd);
	}

	putchar('\n');
	return res;
}

static int run_help(struct add_i_state *s, const struct pathspec *ps UNUSED,
		    struct prefix_item_list *files UNUSED,
		    struct list_and_choose_options *opts UNUSED)
{
	color_fprintf_ln(stdout, s->help_color, "status        - %s",
			 _("show paths with changes"));
	color_fprintf_ln(stdout, s->help_color, "update        - %s",
			 _("add working tree state to the staged set of changes"));
	color_fprintf_ln(stdout, s->help_color, "revert        - %s",
			 _("revert staged set of changes back to the HEAD version"));
	color_fprintf_ln(stdout, s->help_color, "patch         - %s",
			 _("pick hunks and update selectively"));
	color_fprintf_ln(stdout, s->help_color, "diff          - %s",
			 _("view diff between HEAD and index"));
	color_fprintf_ln(stdout, s->help_color, "add untracked - %s",
			 _("add contents of untracked files to the staged set of changes"));

	return 0;
}

static void choose_prompt_help(struct add_i_state *s)
{
	color_fprintf_ln(stdout, s->help_color, "%s",
			 _("Prompt help:"));
	color_fprintf_ln(stdout, s->help_color, "1          - %s",
			 _("select a single item"));
	color_fprintf_ln(stdout, s->help_color, "3-5        - %s",
			 _("select a range of items"));
	color_fprintf_ln(stdout, s->help_color, "2-3,6-9    - %s",
			 _("select multiple ranges"));
	color_fprintf_ln(stdout, s->help_color, "foo        - %s",
			 _("select item based on unique prefix"));
	color_fprintf_ln(stdout, s->help_color, "-...       - %s",
			 _("unselect specified items"));
	color_fprintf_ln(stdout, s->help_color, "*          - %s",
			 _("choose all items"));
	color_fprintf_ln(stdout, s->help_color, "           - %s",
			 _("(empty) finish selecting"));
}

typedef int (*command_t)(struct add_i_state *s, const struct pathspec *ps,
			 struct prefix_item_list *files,
			 struct list_and_choose_options *opts);

struct command_item {
	size_t prefix_length;
	command_t command;
};

struct print_command_item_data {
	const char *color, *reset;
};

static void print_command_item(int i, int selected UNUSED,
			       struct string_list_item *item,
			       void *print_command_item_data)
{
	struct print_command_item_data *d = print_command_item_data;
	struct command_item *util = item->util;

	if (!util->prefix_length ||
	    !is_valid_prefix(item->string, util->prefix_length))
		printf(" %2d: %s", i + 1, item->string);
	else
		printf(" %2d: %s%.*s%s%s", i + 1,
		       d->color, (int)util->prefix_length, item->string,
		       d->reset, item->string + util->prefix_length);
}

static void command_prompt_help(struct add_i_state *s)
{
	const char *help_color = s->help_color;
	color_fprintf_ln(stdout, help_color, "%s", _("Prompt help:"));
	color_fprintf_ln(stdout, help_color, "1          - %s",
			 _("select a numbered item"));
	color_fprintf_ln(stdout, help_color, "foo        - %s",
			 _("select item based on unique prefix"));
	color_fprintf_ln(stdout, help_color, "           - %s",
			 _("(empty) select nothing"));
}

int run_add_i(struct repository *r, const struct pathspec *ps,
	      struct add_p_opt *add_p_opt)
{
	struct add_i_state s = { NULL };
	struct print_command_item_data data = { "[", "]" };
	struct list_and_choose_options main_loop_opts = {
		{ 4, N_("*** Commands ***"), print_command_item, &data },
		N_("What now"), SINGLETON | IMMEDIATE, command_prompt_help
	};
	struct {
		const char *string;
		command_t command;
	} command_list[] = {
		{ "status", run_status },
		{ "update", run_update },
		{ "revert", run_revert },
		{ "add untracked", run_add_untracked },
		{ "patch", run_patch },
		{ "diff", run_diff },
		{ "quit", NULL },
		{ "help", run_help },
	};
	struct prefix_item_list commands = PREFIX_ITEM_LIST_INIT;

	struct print_file_item_data print_file_item_data = {
		"%12s %12s %s", NULL, NULL,
		STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
	};
	struct list_and_choose_options opts = {
		{ 0, NULL, print_file_item, &print_file_item_data },
		NULL, 0, choose_prompt_help
	};
	struct strbuf header = STRBUF_INIT;
	struct prefix_item_list files = PREFIX_ITEM_LIST_INIT;
	ssize_t i;
	int res = 0;

	for (i = 0; i < ARRAY_SIZE(command_list); i++) {
		struct command_item *util = xcalloc(1, sizeof(*util));
		util->command = command_list[i].command;
		string_list_append(&commands.items, command_list[i].string)
			->util = util;
	}

	init_add_i_state(&s, r, add_p_opt);

	/*
	 * When color was asked for, use the prompt color for
	 * highlighting, otherwise use square brackets.
	 */
	if (want_color(s.use_color_interactive)) {
		data.color = s.prompt_color;
		data.reset = s.reset_color_interactive;
	}
	print_file_item_data.color = data.color;
	print_file_item_data.reset = data.reset;

	strbuf_addstr(&header, "     ");
	strbuf_addf(&header, print_file_item_data.modified_fmt,
		    _("staged"), _("unstaged"), _("path"));
	opts.list_opts.header = header.buf;

	discard_index(r->index);
	if (repo_read_index(r) < 0 ||
	    repo_refresh_and_write_index(r, REFRESH_QUIET, 0, 1,
					 NULL, NULL, NULL) < 0)
		warning(_("could not refresh index"));

	res = run_status(&s, ps, &files, &opts);

	for (;;) {
		struct command_item *util;

		i = list_and_choose(&s, &commands, &main_loop_opts);
		if (i < 0 || i >= commands.items.nr)
			util = NULL;
		else
			util = commands.items.items[i].util;

		if (i == LIST_AND_CHOOSE_QUIT || (util && !util->command)) {
			printf(_("Bye.\n"));
			res = 0;
			break;
		}

		if (util)
			res = util->command(&s, ps, &files, &opts);
	}

	prefix_item_list_clear(&files);
	strbuf_release(&print_file_item_data.buf);
	strbuf_release(&print_file_item_data.name);
	strbuf_release(&print_file_item_data.index);
	strbuf_release(&print_file_item_data.worktree);
	strbuf_release(&header);
	prefix_item_list_clear(&commands);
	clear_add_i_state(&s);

	return res;
}
