/*
 * "git clean" builtin command
 *
 * Copyright (C) 2007 Shawn Bohrer
 *
 * Based on git-clean.sh by Pavel Roskin
 */

#include "builtin.h"
#include "cache.h"
#include "dir.h"
#include "parse-options.h"

static int force = -1; /* unset */

static const char *const builtin_clean_usage[] = {
	"git-clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...",
	NULL
};

static int git_clean_config(const char *var, const char *value)
{
	if (!strcmp(var, "clean.requireforce"))
		force = !git_config_bool(var, value);
	return git_default_config(var, value);
}

int cmd_clean(int argc, const char **argv, const char *prefix)
{
	int i;
	int show_only = 0, remove_directories = 0, quiet = 0, ignored = 0;
	int ignored_only = 0, baselen = 0, config_set = 0;
	struct strbuf directory;
	struct dir_struct dir;
	const char *path, *base;
	static const char **pathspec;
	char *seen = NULL;
	struct option options[] = {
		OPT__QUIET(&quiet),
		OPT__DRY_RUN(&show_only),
		OPT_BOOLEAN('f', NULL, &force, "force"),
		OPT_BOOLEAN('d', NULL, &remove_directories,
				"remove whole directories"),
		OPT_BOOLEAN('x', NULL, &ignored, "remove ignored files, too"),
		OPT_BOOLEAN('X', NULL, &ignored_only,
				"remove only ignored files"),
		OPT_END()
	};

	git_config(git_clean_config);
	if (force < 0)
		force = 0;
	else
		config_set = 1;

	argc = parse_options(argc, argv, options, builtin_clean_usage, 0);

	memset(&dir, 0, sizeof(dir));
	if (ignored_only)
		dir.show_ignored = 1;

	if (ignored && ignored_only)
		die("-x and -X cannot be used together");

	if (!show_only && !force)
		die("clean.requireForce%s set and -n or -f not given; "
		    "refusing to clean", config_set ? "" : " not");

	dir.show_other_directories = 1;

	if (!ignored)
		setup_standard_excludes(&dir);

	pathspec = get_pathspec(prefix, argv);
	read_cache();

	/*
	 * Calculate common prefix for the pathspec, and
	 * use that to optimize the directory walk
	 */
	baselen = common_prefix(pathspec);
	path = ".";
	base = "";
	if (baselen)
		path = base = xmemdupz(*pathspec, baselen);
	read_directory(&dir, path, base, baselen, pathspec);
	strbuf_init(&directory, 0);

	if (pathspec)
		seen = xmalloc(argc);

	for (i = 0; i < dir.nr; i++) {
		struct dir_entry *ent = dir.entries[i];
		int len, pos, matches;
		struct cache_entry *ce;
		struct stat st;

		/*
		 * Remove the '/' at the end that directory
		 * walking adds for directory entries.
		 */
		len = ent->len;
		if (len && ent->name[len-1] == '/')
			len--;
		pos = cache_name_pos(ent->name, len);
		if (0 <= pos)
			continue;	/* exact match */
		pos = -pos - 1;
		if (pos < active_nr) {
			ce = active_cache[pos];
			if (ce_namelen(ce) == len &&
			    !memcmp(ce->name, ent->name, len))
				continue; /* Yup, this one exists unmerged */
		}

		/*
		 * we might have removed this as part of earlier
		 * recursive directory removal, so lstat() here could
		 * fail with ENOENT.
		 */
		if (lstat(ent->name, &st))
			continue;

		if (pathspec) {
			memset(seen, 0, argc);
			matches = match_pathspec(pathspec, ent->name, ent->len,
						 baselen, seen);
		} else {
			matches = 0;
		}

		if (S_ISDIR(st.st_mode)) {
			strbuf_addstr(&directory, ent->name);
			if (show_only && (remove_directories || matches)) {
				printf("Would remove %s\n", directory.buf);
			} else if (quiet && (remove_directories || matches)) {
				remove_dir_recursively(&directory, 0);
			} else if (remove_directories || matches) {
				printf("Removing %s\n", directory.buf);
				remove_dir_recursively(&directory, 0);
			} else if (show_only) {
				printf("Would not remove %s\n", directory.buf);
			} else {
				printf("Not removing %s\n", directory.buf);
			}
			strbuf_reset(&directory);
		} else {
			if (pathspec && !matches)
				continue;
			if (show_only) {
				printf("Would remove %s\n", ent->name);
				continue;
			} else if (!quiet) {
				printf("Removing %s\n", ent->name);
			}
			unlink(ent->name);
		}
	}
	free(seen);

	strbuf_release(&directory);
	return 0;
}
