/*
 * GIT - The information manager from hell
 *
 * Copyright (C) Linus Torvalds, 2005
 */
#include "cache.h"
#include "diff.h"

static const char *diff_files_usage =
"git-diff-files [-p] [-q] [-r] [-z] [-R] [-B] [-M] [-C] [--find-copies-harder] [-O<orderfile>] [-S<string>] [--pickaxe-all] [<path>...]";

static int diff_output_format = DIFF_FORMAT_HUMAN;
static int detect_rename = 0;
static int find_copies_harder = 0;
static int diff_setup_opt = 0;
static int diff_score_opt = 0;
static const char *pickaxe = NULL;
static int pickaxe_opts = 0;
static int diff_break_opt = -1;
static const char *orderfile = NULL;
static const char *diff_filter = NULL;
static int silent = 0;

static void show_unmerge(const char *path)
{
	diff_unmerge(path);
}

static void show_file(int pfx, struct cache_entry *ce)
{
	diff_addremove(pfx, ntohl(ce->ce_mode), ce->sha1, ce->name, NULL);
}

static void show_modified(int oldmode, int mode,
			  const unsigned char *old_sha1, const unsigned char *sha1,
			  char *path)
{
	diff_change(oldmode, mode, old_sha1, sha1, path, NULL);
}

int main(int argc, const char **argv)
{
	static const unsigned char null_sha1[20] = { 0, };
	int entries = read_cache();
	int i;

	while (1 < argc && argv[1][0] == '-') {
		if (!strcmp(argv[1], "-p") || !strcmp(argv[1], "-u"))
			diff_output_format = DIFF_FORMAT_PATCH;
		else if (!strcmp(argv[1], "-q"))
			silent = 1;
		else if (!strcmp(argv[1], "-r"))
			; /* no-op */
		else if (!strcmp(argv[1], "-s"))
			; /* no-op */
		else if (!strcmp(argv[1], "-z"))
			diff_output_format = DIFF_FORMAT_MACHINE;
		else if (!strcmp(argv[1], "-R"))
			diff_setup_opt |= DIFF_SETUP_REVERSE;
		else if (!strncmp(argv[1], "-S", 2))
			pickaxe = argv[1] + 2;
		else if (!strncmp(argv[1], "-O", 2))
			orderfile = argv[1] + 2;
		else if (!strncmp(argv[1], "--diff-filter=", 14))
			diff_filter = argv[1] + 14;
		else if (!strcmp(argv[1], "--pickaxe-all"))
			pickaxe_opts = DIFF_PICKAXE_ALL;
		else if (!strncmp(argv[1], "-B", 2)) {
			if ((diff_break_opt =
			     diff_scoreopt_parse(argv[1])) == -1)
				usage(diff_files_usage);
		}
		else if (!strncmp(argv[1], "-M", 2)) {
			if ((diff_score_opt =
			     diff_scoreopt_parse(argv[1])) == -1)
				usage(diff_files_usage);
			detect_rename = DIFF_DETECT_RENAME;
		}
		else if (!strncmp(argv[1], "-C", 2)) {
			if ((diff_score_opt =
			     diff_scoreopt_parse(argv[1])) == -1)
				usage(diff_files_usage);
			detect_rename = DIFF_DETECT_COPY;
		}
		else if (!strcmp(argv[1], "--find-copies-harder"))
			find_copies_harder = 1;
		else
			usage(diff_files_usage);
		argv++; argc--;
	}

	if (find_copies_harder && detect_rename != DIFF_DETECT_COPY)
		usage(diff_files_usage);

	/* At this point, if argc == 1, then we are doing everything.
	 * Otherwise argv[1] .. argv[argc-1] have the explicit paths.
	 */
	if (entries < 0) {
		perror("read_cache");
		exit(1);
	}

	diff_setup(diff_setup_opt);

	for (i = 0; i < entries; i++) {
		struct stat st;
		unsigned int oldmode;
		struct cache_entry *ce = active_cache[i];
		int changed;

		if (ce_stage(ce)) {
			show_unmerge(ce->name);
			while (i < entries &&
			       !strcmp(ce->name, active_cache[i]->name))
				i++;
			i--; /* compensate for loop control increments */
			continue;
		}

		if (lstat(ce->name, &st) < 0) {
			if (errno != ENOENT && errno != ENOTDIR) {
				perror(ce->name);
				continue;
			}
			if (silent)
				continue;
			show_file('-', ce);
			continue;
		}
		changed = ce_match_stat(ce, &st);
		if (!changed && !find_copies_harder)
			continue;
		oldmode = ntohl(ce->ce_mode);
		show_modified(oldmode, DIFF_FILE_CANON_MODE(st.st_mode),
			      ce->sha1, (changed ? null_sha1 : ce->sha1),
			      ce->name);
	}
	diffcore_std((1 < argc) ? argv + 1 : NULL,
		     detect_rename, diff_score_opt,
		     pickaxe, pickaxe_opts,
		     diff_break_opt,
		     orderfile, diff_filter);
	diff_flush(diff_output_format);
	return 0;
}
