#define USE_THE_REPOSITORY_VARIABLE

#include "builtin.h"
#include "gettext.h"
#include "object-name.h"
#include "parse-options.h"
#include "range-diff.h"
#include "config.h"
#include "parse.h"


static const char * const builtin_range_diff_usage[] = {
N_("git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>"),
N_("git range-diff [<options>] <old-tip>...<new-tip>"),
N_("git range-diff [<options>] <base> <old-tip> <new-tip>"),
NULL
};

static int parse_max_memory(const struct option *opt, const char *arg, int unset)
{
	size_t *max_memory = opt->value;
	uintmax_t val;

	if (unset)
		return 0;

	if (!git_parse_unsigned(arg, &val, SIZE_MAX))
		return error(_("invalid max-memory value: %s"), arg);

	*max_memory = (size_t)val;
	return 0;
}

int cmd_range_diff(int argc,
		   const char **argv,
		   const char *prefix,
		   struct repository *repo UNUSED)
{
	struct diff_options diffopt = { NULL };
	struct strvec other_arg = STRVEC_INIT;
	struct strvec diff_merges_arg = STRVEC_INIT;
	struct range_diff_options range_diff_opts = {
		.creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT,
		.max_memory = RANGE_DIFF_MAX_MEMORY_DEFAULT,
		.diffopt = &diffopt,
		.other_arg = &other_arg
	};
	int simple_color = -1, left_only = 0, right_only = 0;
	struct option range_diff_options[] = {
		OPT_INTEGER(0, "creation-factor",
			    &range_diff_opts.creation_factor,
			    N_("percentage by which creation is weighted")),
		OPT_BOOL(0, "no-dual-color", &simple_color,
			    N_("use simple diff colors")),
		OPT_PASSTHRU_ARGV(0, "notes", &other_arg,
				  N_("notes"), N_("passed to 'git log'"),
				  PARSE_OPT_OPTARG),
		OPT_PASSTHRU_ARGV(0, "diff-merges", &diff_merges_arg,
				  N_("style"), N_("passed to 'git log'"), 0),
		OPT_CALLBACK(0, "max-memory", &range_diff_opts.max_memory,
			     N_("size"),
			     N_("maximum memory for cost matrix (default 4G)"),
			     parse_max_memory),
		OPT_PASSTHRU_ARGV(0, "remerge-diff", &diff_merges_arg, NULL,
				  N_("passed to 'git log'"), PARSE_OPT_NOARG),
		OPT_BOOL(0, "left-only", &left_only,
			 N_("only emit output related to the first range")),
		OPT_BOOL(0, "right-only", &right_only,
			 N_("only emit output related to the second range")),
		OPT_END()
	};
	struct option *options;
	int i, dash_dash = -1, res = 0;
	struct strbuf range1 = STRBUF_INIT, range2 = STRBUF_INIT;
	struct object_id oid;
	const char *three_dots = NULL;

	repo_config(the_repository, git_diff_ui_config, NULL);

	repo_diff_setup(the_repository, &diffopt);

	options = add_diff_options(range_diff_options, &diffopt);
	argc = parse_options(argc, argv, prefix, options,
			     builtin_range_diff_usage, PARSE_OPT_KEEP_DASHDASH);

	diff_setup_done(&diffopt);

	/* force color when --dual-color was used */
	if (!simple_color)
		diffopt.use_color = 1;

	/* If `--diff-merges` was specified, imply `--merges` */
	if (diff_merges_arg.nr) {
		range_diff_opts.include_merges = 1;
		strvec_pushv(&other_arg, diff_merges_arg.v);
	}

	for (i = 0; i < argc; i++)
		if (!strcmp(argv[i], "--")) {
			dash_dash = i;
			break;
		}

	if (dash_dash == 3 ||
	    (dash_dash < 0 && argc > 2 &&
	     !repo_get_oid_committish(the_repository, argv[0], &oid) &&
	     !repo_get_oid_committish(the_repository, argv[1], &oid) &&
	     !repo_get_oid_committish(the_repository, argv[2], &oid))) {
		if (dash_dash < 0)
			; /* already validated arguments */
		else if (repo_get_oid_committish(the_repository, argv[0], &oid))
			usage_msg_optf(_("not a revision: '%s'"),
				       builtin_range_diff_usage, options,
				       argv[0]);
		else if (repo_get_oid_committish(the_repository, argv[1], &oid))
			usage_msg_optf(_("not a revision: '%s'"),
				       builtin_range_diff_usage, options,
				       argv[1]);
		else if (repo_get_oid_committish(the_repository, argv[2], &oid))
			usage_msg_optf(_("not a revision: '%s'"),
				       builtin_range_diff_usage, options,
				       argv[2]);

		strbuf_addf(&range1, "%s..%s", argv[0], argv[1]);
		strbuf_addf(&range2, "%s..%s", argv[0], argv[2]);

		strvec_pushv(&other_arg, argv +
			     (dash_dash < 0 ? 3 : dash_dash));
	} else if (dash_dash == 2 ||
		   (dash_dash < 0 && argc > 1 &&
		    is_range_diff_range(argv[0]) &&
		    is_range_diff_range(argv[1]))) {
		if (dash_dash < 0)
			; /* already validated arguments */
		else if (!is_range_diff_range(argv[0]))
			usage_msg_optf(_("not a commit range: '%s'"),
				       builtin_range_diff_usage, options,
				       argv[0]);
		else if (!is_range_diff_range(argv[1]))
			usage_msg_optf(_("not a commit range: '%s'"),
				       builtin_range_diff_usage, options,
				       argv[1]);

		strbuf_addstr(&range1, argv[0]);
		strbuf_addstr(&range2, argv[1]);

		strvec_pushv(&other_arg, argv +
			     (dash_dash < 0 ? 2 : dash_dash));
	} else if (dash_dash == 1 ||
		   (dash_dash < 0 && argc > 0 &&
		    (three_dots = strstr(argv[0], "...")))) {
		const char *a, *b;
		int a_len;

		if (dash_dash < 0)
			; /* already validated arguments */
		else if (!(three_dots = strstr(argv[0], "...")))
			usage_msg_optf(_("not a symmetric range: '%s'"),
					 builtin_range_diff_usage, options,
					 argv[0]);

		if (three_dots == argv[0]) {
			a = "HEAD";
			a_len = strlen(a);
		} else {
			a = argv[0];
			a_len = (int)(three_dots - a);
		}

		if (three_dots[3])
			b = three_dots + 3;
		else
			b = "HEAD";

		strbuf_addf(&range1, "%s..%.*s", b, a_len, a);
		strbuf_addf(&range2, "%.*s..%s", a_len, a, b);

		strvec_pushv(&other_arg, argv +
			     (dash_dash < 0 ? 1 : dash_dash));
	} else
		usage_msg_opt(_("need two commit ranges"),
			      builtin_range_diff_usage, options);
	FREE_AND_NULL(options);

	range_diff_opts.dual_color = simple_color < 1;
	range_diff_opts.left_only = left_only;
	range_diff_opts.right_only = right_only;
	res = show_range_diff(range1.buf, range2.buf, &range_diff_opts);

	strvec_clear(&other_arg);
	strvec_clear(&diff_merges_arg);
	strbuf_release(&range1);
	strbuf_release(&range2);

	return res;
}
