/*
 * Copyright (c) 2005 Junio C Hamano
 */

#include "cache.h"
#include "diff.h"

static struct diff_options diff_options;

static const char diff_stages_usage[] =
"git-diff-stages [<common diff options>] <stage1> <stage2> [<path>...]"
COMMON_DIFF_OPTIONS_HELP;

static void diff_stages(int stage1, int stage2)
{
	int i = 0;
	while (i < active_nr) {
		struct cache_entry *ce, *stages[4] = { NULL, };
		struct cache_entry *one, *two;
		const char *name;
		int len;
		ce = active_cache[i];
		len = ce_namelen(ce);
		name = ce->name;
		for (;;) {
			int stage = ce_stage(ce);
			stages[stage] = ce;
			if (active_nr <= ++i)
				break;
			ce = active_cache[i];
			if (ce_namelen(ce) != len ||
			    memcmp(name, ce->name, len))
				break;
		}
		one = stages[stage1];
		two = stages[stage2];
		if (!one && !two)
			continue;
		if (!one)
			diff_addremove(&diff_options, '+', ntohl(two->ce_mode),
				       two->sha1, name, NULL);
		else if (!two)
			diff_addremove(&diff_options, '-', ntohl(one->ce_mode),
				       one->sha1, name, NULL);
		else if (memcmp(one->sha1, two->sha1, 20) ||
			 (one->ce_mode != two->ce_mode) ||
			 diff_options.find_copies_harder)
			diff_change(&diff_options,
				    ntohl(one->ce_mode), ntohl(two->ce_mode),
				    one->sha1, two->sha1, name, NULL);
	}
}

int main(int ac, const char **av)
{
	int stage1, stage2;

	setup_git_directory();

	git_config(git_diff_config);
	read_cache();
	diff_setup(&diff_options);
	while (1 < ac && av[1][0] == '-') {
		const char *arg = av[1];
		if (!strcmp(arg, "-r"))
			; /* as usual */
		else {
			int diff_opt_cnt;
			diff_opt_cnt = diff_opt_parse(&diff_options,
						      av+1, ac-1);
			if (diff_opt_cnt < 0)
				usage(diff_stages_usage);
			else if (diff_opt_cnt) {
				av += diff_opt_cnt;
				ac -= diff_opt_cnt;
				continue;
			}
			else
				usage(diff_stages_usage);
		}
		ac--; av++;
	}

	if (ac < 3 ||
	    sscanf(av[1], "%d", &stage1) != 1 ||
	    ! (0 <= stage1 && stage1 <= 3) ||
	    sscanf(av[2], "%d", &stage2) != 1 ||
	    ! (0 <= stage2 && stage2 <= 3))
		usage(diff_stages_usage);

	av += 3; /* The rest from av[0] are for paths restriction. */
	diff_options.paths = av;

	if (diff_setup_done(&diff_options) < 0)
		usage(diff_stages_usage);

	diff_stages(stage1, stage2);
	diffcore_std(&diff_options);
	diff_flush(&diff_options);
	return 0;
}
