/*
 * "git mv" builtin command
 *
 * Copyright (C) 2006 Johannes Schindelin
 */
#include <fnmatch.h>

#include "cache.h"
#include "builtin.h"
#include "dir.h"
#include "cache-tree.h"
#include "path-list.h"

static const char builtin_mv_usage[] =
"git-mv [-n] [-f] (<source> <destination> | [-k] <source>... <destination>)";

static const char **copy_pathspec(const char *prefix, const char **pathspec,
				  int count, int base_name)
{
	const char **result = xmalloc((count + 1) * sizeof(const char *));
	memcpy(result, pathspec, count * sizeof(const char *));
	result[count] = NULL;
	if (base_name) {
		int i;
		for (i = 0; i < count; i++) {
			const char *last_slash = strrchr(result[i], '/');
			if (last_slash)
				result[i] = last_slash + 1;
		}
	}
	return get_pathspec(prefix, result);
}

static void show_list(const char *label, struct path_list *list)
{
	if (list->nr > 0) {
		int i;
		printf("%s", label);
		for (i = 0; i < list->nr; i++)
			printf("%s%s", i > 0 ? ", " : "", list->items[i].path);
		putchar('\n');
	}
}

static const char *add_slash(const char *path)
{
	int len = strlen(path);
	if (path[len - 1] != '/') {
		char *with_slash = xmalloc(len + 2);
		memcpy(with_slash, path, len);
		strcat(with_slash + len, "/");
		return with_slash;
	}
	return path;
}

static struct lock_file lock_file;

int cmd_mv(int argc, const char **argv, const char *prefix)
{
	int i, newfd, count;
	int verbose = 0, show_only = 0, force = 0, ignore_errors = 0;
	const char **source, **destination, **dest_path;
	enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes;
	struct stat st;
	struct path_list overwritten = {NULL, 0, 0, 0};
	struct path_list src_for_dst = {NULL, 0, 0, 0};
	struct path_list added = {NULL, 0, 0, 0};
	struct path_list deleted = {NULL, 0, 0, 0};
	struct path_list changed = {NULL, 0, 0, 0};

	git_config(git_default_config);

	newfd = hold_lock_file_for_update(&lock_file, get_index_file());
	if (newfd < 0)
		die("unable to create new index file");

	if (read_cache() < 0)
		die("index file corrupt");

	for (i = 1; i < argc; i++) {
		const char *arg = argv[i];

		if (arg[0] != '-')
			break;
		if (!strcmp(arg, "--")) {
			i++;
			break;
		}
		if (!strcmp(arg, "-n")) {
			show_only = 1;
			continue;
		}
		if (!strcmp(arg, "-f")) {
			force = 1;
			continue;
		}
		if (!strcmp(arg, "-k")) {
			ignore_errors = 1;
			continue;
		}
		die(builtin_mv_usage);
	}
	count = argc - i - 1;
	if (count < 1)
		usage(builtin_mv_usage);

	source = copy_pathspec(prefix, argv + i, count, 0);
	modes = xcalloc(count, sizeof(enum update_mode));
	dest_path = copy_pathspec(prefix, argv + argc - 1, 1, 0);

	if (!lstat(dest_path[0], &st) &&
			S_ISDIR(st.st_mode)) {
		dest_path[0] = add_slash(dest_path[0]);
		destination = copy_pathspec(dest_path[0], argv + i, count, 1);
	} else {
		if (count != 1)
			usage(builtin_mv_usage);
		destination = dest_path;
	}

	/* Checking */
	for (i = 0; i < count; i++) {
		const char *bad = NULL;

		if (show_only)
			printf("Checking rename of '%s' to '%s'\n",
				source[i], destination[i]);

		if (lstat(source[i], &st) < 0)
			bad = "bad source";

		if (S_ISDIR(st.st_mode)) {
			const char *dir = source[i], *dest_dir = destination[i];
			int first, last, len = strlen(dir);

			if (lstat(dest_dir, &st) == 0) {
				bad = "cannot move directory over file";
				goto next;
			}

			modes[i] = WORKING_DIRECTORY;

			first = cache_name_pos(source[i], len);
			if (first >= 0)
				die ("Huh? %s/ is in index?", dir);

			first = -1 - first;
			for (last = first; last < active_nr; last++) {
				const char *path = active_cache[last]->name;
				if (strncmp(path, dir, len) || path[len] != '/')
					break;
			}

			if (last - first < 1)
				bad = "source directory is empty";
			else if (!bad) {
				int j, dst_len = strlen(dest_dir);

				if (last - first > 0) {
					source = realloc(source,
							(count + last - first)
							* sizeof(char *));
					destination = realloc(destination,
							(count + last - first)
							* sizeof(char *));
					modes = realloc(modes,
							(count + last - first)
							* sizeof(enum update_mode));
				}

				dest_dir = add_slash(dest_dir);

				for (j = 0; j < last - first; j++) {
					const char *path =
						active_cache[first + j]->name;
					source[count + j] = path;
					destination[count + j] =
						prefix_path(dest_dir, dst_len,
							path + len);
					modes[count + j] = INDEX;
				}
				count += last - first;
			}

			goto next;
		}

		if (!bad && lstat(destination[i], &st) == 0) {
			bad = "destination exists";
			if (force) {
				/*
				 * only files can overwrite each other:
				 * check both source and destination
				 */
				if (S_ISREG(st.st_mode)) {
					fprintf(stderr, "Warning: %s;"
							" will overwrite!\n",
							bad);
					bad = NULL;
					path_list_insert(destination[i],
							&overwritten);
				} else
					bad = "Cannot overwrite";
			}
		}

		if (!bad &&
		    !strncmp(destination[i], source[i], strlen(source[i])))
			bad = "can not move directory into itself";

		if (!bad && cache_name_pos(source[i], strlen(source[i])) < 0)
			bad = "not under version control";

		if (!bad) {
			if (path_list_has_path(&src_for_dst, destination[i]))
				bad = "multiple sources for the same target";
			else
				path_list_insert(destination[i], &src_for_dst);
		}

next:
		if (bad) {
			if (ignore_errors) {
				if (--count > 0) {
					memmove(source + i, source + i + 1,
						(count - i) * sizeof(char *));
					memmove(destination + i,
						destination + i + 1,
						(count - i) * sizeof(char *));
				}
			} else
				die ("%s, source=%s, destination=%s",
				     bad, source[i], destination[i]);
		}
	}

	for (i = 0; i < count; i++) {
		if (show_only || verbose)
			printf("Renaming %s to %s\n",
			       source[i], destination[i]);
		if (!show_only && modes[i] != INDEX &&
		    rename(source[i], destination[i]) < 0 &&
		    !ignore_errors)
			die ("renaming %s failed: %s",
			     source[i], strerror(errno));

		if (modes[i] == WORKING_DIRECTORY)
			continue;

		if (cache_name_pos(source[i], strlen(source[i])) >= 0) {
			path_list_insert(source[i], &deleted);

			/* destination can be a directory with 1 file inside */
			if (path_list_has_path(&overwritten, destination[i]))
				path_list_insert(destination[i], &changed);
			else
				path_list_insert(destination[i], &added);
		} else
			path_list_insert(destination[i], &added);
	}

        if (show_only) {
		show_list("Changed  : ", &changed);
		show_list("Adding   : ", &added);
		show_list("Deleting : ", &deleted);
	} else {
		for (i = 0; i < changed.nr; i++) {
			const char *path = changed.items[i].path;
			int i = cache_name_pos(path, strlen(path));
			struct cache_entry *ce = active_cache[i];

			if (i < 0)
				die ("Huh? Cache entry for %s unknown?", path);
			refresh_cache_entry(ce, 0);
		}

		for (i = 0; i < added.nr; i++) {
			const char *path = added.items[i].path;
			add_file_to_index(path, verbose);
		}

		for (i = 0; i < deleted.nr; i++) {
			const char *path = deleted.items[i].path;
			remove_file_from_cache(path);
		}

		if (active_cache_changed) {
			if (write_cache(newfd, active_cache, active_nr) ||
			    close(newfd) ||
			    commit_lock_file(&lock_file))
				die("Unable to write new index file");
		}
	}

	return 0;
}
