#include "git-compat-util.h"
#include "line-range.h"
#include "cache.h"
#include "tag.h"
#include "blob.h"
#include "tree.h"
#include "diff.h"
#include "commit.h"
#include "decorate.h"
#include "revision.h"
#include "xdiff-interface.h"
#include "strbuf.h"
#include "log-tree.h"
#include "graph.h"
#include "userdiff.h"
#include "line-log.h"
#include "argv-array.h"

static void range_set_grow(struct range_set *rs, size_t extra)
{
	ALLOC_GROW(rs->ranges, rs->nr + extra, rs->alloc);
}

/* Either initialization would be fine */
#define RANGE_SET_INIT {0}

void range_set_init(struct range_set *rs, size_t prealloc)
{
	rs->alloc = rs->nr = 0;
	rs->ranges = NULL;
	if (prealloc)
		range_set_grow(rs, prealloc);
}

void range_set_release(struct range_set *rs)
{
	free(rs->ranges);
	rs->alloc = rs->nr = 0;
	rs->ranges = NULL;
}

/* dst must be uninitialized! */
static void range_set_copy(struct range_set *dst, struct range_set *src)
{
	range_set_init(dst, src->nr);
	memcpy(dst->ranges, src->ranges, src->nr*sizeof(struct range_set));
	dst->nr = src->nr;
}
static void range_set_move(struct range_set *dst, struct range_set *src)
{
	range_set_release(dst);
	dst->ranges = src->ranges;
	dst->nr = src->nr;
	dst->alloc = src->alloc;
	src->ranges = NULL;
	src->alloc = src->nr = 0;
}

/* tack on a _new_ range _at the end_ */
void range_set_append_unsafe(struct range_set *rs, long a, long b)
{
	assert(a <= b);
	range_set_grow(rs, 1);
	rs->ranges[rs->nr].start = a;
	rs->ranges[rs->nr].end = b;
	rs->nr++;
}

void range_set_append(struct range_set *rs, long a, long b)
{
	assert(rs->nr == 0 || rs->ranges[rs->nr-1].end <= a);
	range_set_append_unsafe(rs, a, b);
}

static int range_cmp(const void *_r, const void *_s)
{
	const struct range *r = _r;
	const struct range *s = _s;

	/* this could be simply 'return r.start-s.start', but for the types */
	if (r->start == s->start)
		return 0;
	if (r->start < s->start)
		return -1;
	return 1;
}

/*
 * Check that the ranges are non-empty, sorted and non-overlapping
 */
static void range_set_check_invariants(struct range_set *rs)
{
	int i;

	if (!rs)
		return;

	if (rs->nr)
		assert(rs->ranges[0].start < rs->ranges[0].end);

	for (i = 1; i < rs->nr; i++) {
		assert(rs->ranges[i-1].end < rs->ranges[i].start);
		assert(rs->ranges[i].start < rs->ranges[i].end);
	}
}

/*
 * In-place pass of sorting and merging the ranges in the range set,
 * to establish the invariants when we get the ranges from the user
 */
void sort_and_merge_range_set(struct range_set *rs)
{
	int i;
	int o = 0; /* output cursor */

	QSORT(rs->ranges, rs->nr, range_cmp);

	for (i = 0; i < rs->nr; i++) {
		if (rs->ranges[i].start == rs->ranges[i].end)
			continue;
		if (o > 0 && rs->ranges[i].start <= rs->ranges[o-1].end) {
			if (rs->ranges[o-1].end < rs->ranges[i].end)
				rs->ranges[o-1].end = rs->ranges[i].end;
		} else {
			rs->ranges[o].start = rs->ranges[i].start;
			rs->ranges[o].end = rs->ranges[i].end;
			o++;
		}
	}
	assert(o <= rs->nr);
	rs->nr = o;

	range_set_check_invariants(rs);
}

/*
 * Union of range sets (i.e., sets of line numbers).  Used to merge
 * them when searches meet at a common ancestor.
 *
 * This is also where the ranges are consolidated into canonical form:
 * overlapping and adjacent ranges are merged, and empty ranges are
 * removed.
 */
static void range_set_union(struct range_set *out,
			     struct range_set *a, struct range_set *b)
{
	int i = 0, j = 0, o = 0;
	struct range *ra = a->ranges;
	struct range *rb = b->ranges;
	/* cannot make an alias of out->ranges: it may change during grow */

	assert(out->nr == 0);
	while (i < a->nr || j < b->nr) {
		struct range *new;
		if (i < a->nr && j < b->nr) {
			if (ra[i].start < rb[j].start)
				new = &ra[i++];
			else if (ra[i].start > rb[j].start)
				new = &rb[j++];
			else if (ra[i].end < rb[j].end)
				new = &ra[i++];
			else
				new = &rb[j++];
		} else if (i < a->nr)      /* b exhausted */
			new = &ra[i++];
		else                       /* a exhausted */
			new = &rb[j++];
		if (new->start == new->end)
			; /* empty range */
		else if (!o || out->ranges[o-1].end < new->start) {
			range_set_grow(out, 1);
			out->ranges[o].start = new->start;
			out->ranges[o].end = new->end;
			o++;
		} else if (out->ranges[o-1].end < new->end) {
			out->ranges[o-1].end = new->end;
		}
	}
	out->nr = o;
}

/*
 * Difference of range sets (out = a \ b).  Pass the "interesting"
 * ranges as 'a' and the target side of the diff as 'b': it removes
 * the ranges for which the commit is responsible.
 */
static void range_set_difference(struct range_set *out,
				  struct range_set *a, struct range_set *b)
{
	int i, j =  0;
	for (i = 0; i < a->nr; i++) {
		long start = a->ranges[i].start;
		long end = a->ranges[i].end;
		while (start < end) {
			while (j < b->nr && start >= b->ranges[j].end)
				/*
				 * a:         |-------
				 * b: ------|
				 */
				j++;
			if (j >= b->nr || end < b->ranges[j].start) {
				/*
				 * b exhausted, or
				 * a:  ----|
				 * b:         |----
				 */
				range_set_append(out, start, end);
				break;
			}
			if (start >= b->ranges[j].start) {
				/*
				 * a:     |--????
				 * b: |------|
				 */
				start = b->ranges[j].end;
			} else if (end > b->ranges[j].start) {
				/*
				 * a: |-----|
				 * b:    |--?????
				 */
				if (start < b->ranges[j].start)
					range_set_append(out, start, b->ranges[j].start);
				start = b->ranges[j].end;
			}
		}
	}
}

static void diff_ranges_init(struct diff_ranges *diff)
{
	range_set_init(&diff->parent, 0);
	range_set_init(&diff->target, 0);
}

static void diff_ranges_release(struct diff_ranges *diff)
{
	range_set_release(&diff->parent);
	range_set_release(&diff->target);
}

static void line_log_data_init(struct line_log_data *r)
{
	memset(r, 0, sizeof(struct line_log_data));
	range_set_init(&r->ranges, 0);
}

static void line_log_data_clear(struct line_log_data *r)
{
	range_set_release(&r->ranges);
	if (r->pair)
		diff_free_filepair(r->pair);
}

static void free_line_log_data(struct line_log_data *r)
{
	while (r) {
		struct line_log_data *next = r->next;
		line_log_data_clear(r);
		free(r);
		r = next;
	}
}

static struct line_log_data *
search_line_log_data(struct line_log_data *list, const char *path,
		     struct line_log_data **insertion_point)
{
	struct line_log_data *p = list;
	if (insertion_point)
		*insertion_point = NULL;
	while (p) {
		int cmp = strcmp(p->path, path);
		if (!cmp)
			return p;
		if (insertion_point && cmp < 0)
			*insertion_point = p;
		p = p->next;
	}
	return NULL;
}

/*
 * Note: takes ownership of 'path', which happens to be what the only
 * caller needs.
 */
static void line_log_data_insert(struct line_log_data **list,
				 char *path,
				 long begin, long end)
{
	struct line_log_data *ip;
	struct line_log_data *p = search_line_log_data(*list, path, &ip);

	if (p) {
		range_set_append_unsafe(&p->ranges, begin, end);
		free(path);
		return;
	}

	p = xcalloc(1, sizeof(struct line_log_data));
	p->path = path;
	range_set_append(&p->ranges, begin, end);
	if (ip) {
		p->next = ip->next;
		ip->next = p;
	} else {
		p->next = *list;
		*list = p;
	}
}

struct collect_diff_cbdata {
	struct diff_ranges *diff;
};

static int collect_diff_cb(long start_a, long count_a,
			   long start_b, long count_b,
			   void *data)
{
	struct collect_diff_cbdata *d = data;

	if (count_a >= 0)
		range_set_append(&d->diff->parent, start_a, start_a + count_a);
	if (count_b >= 0)
		range_set_append(&d->diff->target, start_b, start_b + count_b);

	return 0;
}

static int collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges *out)
{
	struct collect_diff_cbdata cbdata = {NULL};
	xpparam_t xpp;
	xdemitconf_t xecfg;
	xdemitcb_t ecb;

	memset(&xpp, 0, sizeof(xpp));
	memset(&xecfg, 0, sizeof(xecfg));
	xecfg.ctxlen = xecfg.interhunkctxlen = 0;

	cbdata.diff = out;
	xecfg.hunk_func = collect_diff_cb;
	memset(&ecb, 0, sizeof(ecb));
	ecb.priv = &cbdata;
	return xdi_diff(parent, target, &xpp, &xecfg, &ecb);
}

/*
 * These are handy for debugging.  Removing them with #if 0 silences
 * the "unused function" warning.
 */
#if 0
static void dump_range_set(struct range_set *rs, const char *desc)
{
	int i;
	printf("range set %s (%d items):\n", desc, rs->nr);
	for (i = 0; i < rs->nr; i++)
		printf("\t[%ld,%ld]\n", rs->ranges[i].start, rs->ranges[i].end);
}

static void dump_line_log_data(struct line_log_data *r)
{
	char buf[4096];
	while (r) {
		snprintf(buf, 4096, "file %s\n", r->path);
		dump_range_set(&r->ranges, buf);
		r = r->next;
	}
}

static void dump_diff_ranges(struct diff_ranges *diff, const char *desc)
{
	int i;
	assert(diff->parent.nr == diff->target.nr);
	printf("diff ranges %s (%d items):\n", desc, diff->parent.nr);
	printf("\tparent\ttarget\n");
	for (i = 0; i < diff->parent.nr; i++) {
		printf("\t[%ld,%ld]\t[%ld,%ld]\n",
		       diff->parent.ranges[i].start,
		       diff->parent.ranges[i].end,
		       diff->target.ranges[i].start,
		       diff->target.ranges[i].end);
	}
}
#endif


static int ranges_overlap(struct range *a, struct range *b)
{
	return !(a->end <= b->start || b->end <= a->start);
}

/*
 * Given a diff and the set of interesting ranges, determine all hunks
 * of the diff which touch (overlap) at least one of the interesting
 * ranges in the target.
 */
static void diff_ranges_filter_touched(struct diff_ranges *out,
				       struct diff_ranges *diff,
				       struct range_set *rs)
{
	int i, j = 0;

	assert(out->target.nr == 0);

	for (i = 0; i < diff->target.nr; i++) {
		while (diff->target.ranges[i].start > rs->ranges[j].end) {
			j++;
			if (j == rs->nr)
				return;
		}
		if (ranges_overlap(&diff->target.ranges[i], &rs->ranges[j])) {
			range_set_append(&out->parent,
					 diff->parent.ranges[i].start,
					 diff->parent.ranges[i].end);
			range_set_append(&out->target,
					 diff->target.ranges[i].start,
					 diff->target.ranges[i].end);
		}
	}
}

/*
 * Adjust the line counts in 'rs' to account for the lines
 * added/removed in the diff.
 */
static void range_set_shift_diff(struct range_set *out,
				 struct range_set *rs,
				 struct diff_ranges *diff)
{
	int i, j = 0;
	long offset = 0;
	struct range *src = rs->ranges;
	struct range *target = diff->target.ranges;
	struct range *parent = diff->parent.ranges;

	for (i = 0; i < rs->nr; i++) {
		while (j < diff->target.nr && src[i].start >= target[j].start) {
			offset += (parent[j].end-parent[j].start)
				- (target[j].end-target[j].start);
			j++;
		}
		range_set_append(out, src[i].start+offset, src[i].end+offset);
	}
}

/*
 * Given a diff and the set of interesting ranges, map the ranges
 * across the diff.  That is: observe that the target commit takes
 * blame for all the + (target-side) ranges.  So for every pair of
 * ranges in the diff that was touched, we remove the latter and add
 * its parent side.
 */
static void range_set_map_across_diff(struct range_set *out,
				      struct range_set *rs,
				      struct diff_ranges *diff,
				      struct diff_ranges **touched_out)
{
	struct diff_ranges *touched = xmalloc(sizeof(*touched));
	struct range_set tmp1 = RANGE_SET_INIT;
	struct range_set tmp2 = RANGE_SET_INIT;

	diff_ranges_init(touched);
	diff_ranges_filter_touched(touched, diff, rs);
	range_set_difference(&tmp1, rs, &touched->target);
	range_set_shift_diff(&tmp2, &tmp1, diff);
	range_set_union(out, &tmp2, &touched->parent);
	range_set_release(&tmp1);
	range_set_release(&tmp2);

	*touched_out = touched;
}

static struct commit *check_single_commit(struct rev_info *revs)
{
	struct object *commit = NULL;
	int found = -1;
	int i;

	for (i = 0; i < revs->pending.nr; i++) {
		struct object *obj = revs->pending.objects[i].item;
		if (obj->flags & UNINTERESTING)
			continue;
		obj = deref_tag(obj, NULL, 0);
		if (obj->type != OBJ_COMMIT)
			die("Non commit %s?", revs->pending.objects[i].name);
		if (commit)
			die("More than one commit to dig from: %s and %s?",
			    revs->pending.objects[i].name,
			    revs->pending.objects[found].name);
		commit = obj;
		found = i;
	}

	if (!commit)
		die("No commit specified?");

	return (struct commit *) commit;
}

static void fill_blob_sha1(struct commit *commit, struct diff_filespec *spec)
{
	unsigned mode;
	unsigned char sha1[20];

	if (get_tree_entry(commit->object.oid.hash, spec->path,
			   sha1, &mode))
		die("There is no path %s in the commit", spec->path);
	fill_filespec(spec, sha1, 1, mode);

	return;
}

static void fill_line_ends(struct diff_filespec *spec, long *lines,
			   unsigned long **line_ends)
{
	int num = 0, size = 50;
	long cur = 0;
	unsigned long *ends = NULL;
	char *data = NULL;

	if (diff_populate_filespec(spec, 0))
		die("Cannot read blob %s", oid_to_hex(&spec->oid));

	ALLOC_ARRAY(ends, size);
	ends[cur++] = 0;
	data = spec->data;
	while (num < spec->size) {
		if (data[num] == '\n' || num == spec->size - 1) {
			ALLOC_GROW(ends, (cur + 1), size);
			ends[cur++] = num;
		}
		num++;
	}

	/* shrink the array to fit the elements */
	REALLOC_ARRAY(ends, cur);
	*lines = cur-1;
	*line_ends = ends;
}

struct nth_line_cb {
	struct diff_filespec *spec;
	long lines;
	unsigned long *line_ends;
};

static const char *nth_line(void *data, long line)
{
	struct nth_line_cb *d = data;
	assert(d && line <= d->lines);
	assert(d->spec && d->spec->data);

	if (line == 0)
		return (char *)d->spec->data;
	else
		return (char *)d->spec->data + d->line_ends[line] + 1;
}

static struct line_log_data *
parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
{
	long lines = 0;
	unsigned long *ends = NULL;
	struct nth_line_cb cb_data;
	struct string_list_item *item;
	struct line_log_data *ranges = NULL;
	struct line_log_data *p;

	for_each_string_list_item(item, args) {
		const char *name_part, *range_part;
		char *full_name;
		struct diff_filespec *spec;
		long begin = 0, end = 0;
		long anchor;

		name_part = skip_range_arg(item->string);
		if (!name_part || *name_part != ':' || !name_part[1])
			die("-L argument not 'start,end:file' or ':funcname:file': %s",
			    item->string);
		range_part = xstrndup(item->string, name_part - item->string);
		name_part++;

		full_name = prefix_path(prefix, prefix ? strlen(prefix) : 0,
					name_part);

		spec = alloc_filespec(full_name);
		fill_blob_sha1(commit, spec);
		fill_line_ends(spec, &lines, &ends);
		cb_data.spec = spec;
		cb_data.lines = lines;
		cb_data.line_ends = ends;

		p = search_line_log_data(ranges, full_name, NULL);
		if (p && p->ranges.nr)
			anchor = p->ranges.ranges[p->ranges.nr - 1].end + 1;
		else
			anchor = 1;

		if (parse_range_arg(range_part, nth_line, &cb_data,
				    lines, anchor, &begin, &end,
				    full_name))
			die("malformed -L argument '%s'", range_part);
		if (lines < end || ((lines || begin) && lines < begin))
			die("file %s has only %lu lines", name_part, lines);
		if (begin < 1)
			begin = 1;
		if (end < 1)
			end = lines;
		begin--;
		line_log_data_insert(&ranges, full_name, begin, end);

		free_filespec(spec);
		free(ends);
		ends = NULL;
	}

	for (p = ranges; p; p = p->next)
		sort_and_merge_range_set(&p->ranges);

	return ranges;
}

static struct line_log_data *line_log_data_copy_one(struct line_log_data *r)
{
	struct line_log_data *ret = xmalloc(sizeof(*ret));

	assert(r);
	line_log_data_init(ret);
	range_set_copy(&ret->ranges, &r->ranges);

	ret->path = xstrdup(r->path);

	return ret;
}

static struct line_log_data *
line_log_data_copy(struct line_log_data *r)
{
	struct line_log_data *ret = NULL;
	struct line_log_data *tmp = NULL, *prev = NULL;

	assert(r);
	ret = tmp = prev = line_log_data_copy_one(r);
	r = r->next;
	while (r) {
		tmp = line_log_data_copy_one(r);
		prev->next = tmp;
		prev = tmp;
		r = r->next;
	}

	return ret;
}

/* merge two range sets across files */
static struct line_log_data *line_log_data_merge(struct line_log_data *a,
						 struct line_log_data *b)
{
	struct line_log_data *head = NULL, **pp = &head;

	while (a || b) {
		struct line_log_data *src;
		struct line_log_data *src2 = NULL;
		struct line_log_data *d;
		int cmp;
		if (!a)
			cmp = 1;
		else if (!b)
			cmp = -1;
		else
			cmp = strcmp(a->path, b->path);
		if (cmp < 0) {
			src = a;
			a = a->next;
		} else if (cmp == 0) {
			src = a;
			a = a->next;
			src2 = b;
			b = b->next;
		} else {
			src = b;
			b = b->next;
		}
		d = xmalloc(sizeof(struct line_log_data));
		line_log_data_init(d);
		d->path = xstrdup(src->path);
		*pp = d;
		pp = &d->next;
		if (src2)
			range_set_union(&d->ranges, &src->ranges, &src2->ranges);
		else
			range_set_copy(&d->ranges, &src->ranges);
	}

	return head;
}

static void add_line_range(struct rev_info *revs, struct commit *commit,
			   struct line_log_data *range)
{
	struct line_log_data *old = NULL;
	struct line_log_data *new = NULL;

	old = lookup_decoration(&revs->line_log_data, &commit->object);
	if (old && range) {
		new = line_log_data_merge(old, range);
		free_line_log_data(old);
	} else if (range)
		new = line_log_data_copy(range);

	if (new)
		add_decoration(&revs->line_log_data, &commit->object, new);
}

static void clear_commit_line_range(struct rev_info *revs, struct commit *commit)
{
	struct line_log_data *r;
	r = lookup_decoration(&revs->line_log_data, &commit->object);
	if (!r)
		return;
	free_line_log_data(r);
	add_decoration(&revs->line_log_data, &commit->object, NULL);
}

static struct line_log_data *lookup_line_range(struct rev_info *revs,
					       struct commit *commit)
{
	struct line_log_data *ret = NULL;
	struct line_log_data *d;

	ret = lookup_decoration(&revs->line_log_data, &commit->object);

	for (d = ret; d; d = d->next)
		range_set_check_invariants(&d->ranges);

	return ret;
}

void line_log_init(struct rev_info *rev, const char *prefix, struct string_list *args)
{
	struct commit *commit = NULL;
	struct line_log_data *range;

	commit = check_single_commit(rev);
	range = parse_lines(commit, prefix, args);
	add_line_range(rev, commit, range);

	if (!rev->diffopt.detect_rename) {
		struct line_log_data *r;
		struct argv_array array = ARGV_ARRAY_INIT;
		const char **paths;

		for (r = range; r; r = r->next)
			argv_array_push(&array, r->path);
		paths = argv_array_detach(&array);

		parse_pathspec(&rev->diffopt.pathspec, 0,
			       PATHSPEC_PREFER_FULL, "", paths);
		/* strings are now owned by pathspec */
		free(paths);
	}
}

static void move_diff_queue(struct diff_queue_struct *dst,
			    struct diff_queue_struct *src)
{
	assert(src != dst);
	memcpy(dst, src, sizeof(struct diff_queue_struct));
	DIFF_QUEUE_CLEAR(src);
}

static void filter_diffs_for_paths(struct line_log_data *range, int keep_deletions)
{
	int i;
	struct diff_queue_struct outq;
	DIFF_QUEUE_CLEAR(&outq);

	for (i = 0; i < diff_queued_diff.nr; i++) {
		struct diff_filepair *p = diff_queued_diff.queue[i];
		struct line_log_data *rg = NULL;

		if (!DIFF_FILE_VALID(p->two)) {
			if (keep_deletions)
				diff_q(&outq, p);
			else
				diff_free_filepair(p);
			continue;
		}
		for (rg = range; rg; rg = rg->next) {
			if (!strcmp(rg->path, p->two->path))
				break;
		}
		if (rg)
			diff_q(&outq, p);
		else
			diff_free_filepair(p);
	}
	free(diff_queued_diff.queue);
	diff_queued_diff = outq;
}

static inline int diff_might_be_rename(void)
{
	int i;
	for (i = 0; i < diff_queued_diff.nr; i++)
		if (!DIFF_FILE_VALID(diff_queued_diff.queue[i]->one)) {
			/* fprintf(stderr, "diff_might_be_rename found creation of: %s\n", */
			/* 	diff_queued_diff.queue[i]->two->path); */
			return 1;
		}
	return 0;
}

static void queue_diffs(struct line_log_data *range,
			struct diff_options *opt,
			struct diff_queue_struct *queue,
			struct commit *commit, struct commit *parent)
{
	assert(commit);

	DIFF_QUEUE_CLEAR(&diff_queued_diff);
	diff_tree_sha1(parent ? parent->tree->object.oid.hash : NULL,
			commit->tree->object.oid.hash, "", opt);
	if (opt->detect_rename) {
		filter_diffs_for_paths(range, 1);
		if (diff_might_be_rename())
			diffcore_std(opt);
		filter_diffs_for_paths(range, 0);
	}
	move_diff_queue(queue, &diff_queued_diff);
}

static char *get_nth_line(long line, unsigned long *ends, void *data)
{
	if (line == 0)
		return (char *)data;
	else
		return (char *)data + ends[line] + 1;
}

static void print_line(const char *prefix, char first,
		       long line, unsigned long *ends, void *data,
		       const char *color, const char *reset, FILE *file)
{
	char *begin = get_nth_line(line, ends, data);
	char *end = get_nth_line(line+1, ends, data);
	int had_nl = 0;

	if (end > begin && end[-1] == '\n') {
		end--;
		had_nl = 1;
	}

	fputs(prefix, file);
	fputs(color, file);
	putc(first, file);
	fwrite(begin, 1, end-begin, file);
	fputs(reset, file);
	putc('\n', file);
	if (!had_nl)
		fputs("\\ No newline at end of file\n", file);
}

static char *output_prefix(struct diff_options *opt)
{
	char *prefix = "";

	if (opt->output_prefix) {
		struct strbuf *sb = opt->output_prefix(opt, opt->output_prefix_data);
		prefix = sb->buf;
	}

	return prefix;
}

static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *range)
{
	int i, j = 0;
	long p_lines, t_lines;
	unsigned long *p_ends = NULL, *t_ends = NULL;
	struct diff_filepair *pair = range->pair;
	struct diff_ranges *diff = &range->diff;

	struct diff_options *opt = &rev->diffopt;
	char *prefix = output_prefix(opt);
	const char *c_reset = diff_get_color(opt->use_color, DIFF_RESET);
	const char *c_frag = diff_get_color(opt->use_color, DIFF_FRAGINFO);
	const char *c_meta = diff_get_color(opt->use_color, DIFF_METAINFO);
	const char *c_old = diff_get_color(opt->use_color, DIFF_FILE_OLD);
	const char *c_new = diff_get_color(opt->use_color, DIFF_FILE_NEW);
	const char *c_context = diff_get_color(opt->use_color, DIFF_CONTEXT);

	if (!pair || !diff)
		return;

	if (pair->one->oid_valid)
		fill_line_ends(pair->one, &p_lines, &p_ends);
	fill_line_ends(pair->two, &t_lines, &t_ends);

	fprintf(opt->file, "%s%sdiff --git a/%s b/%s%s\n", prefix, c_meta, pair->one->path, pair->two->path, c_reset);
	fprintf(opt->file, "%s%s--- %s%s%s\n", prefix, c_meta,
	       pair->one->oid_valid ? "a/" : "",
	       pair->one->oid_valid ? pair->one->path : "/dev/null",
	       c_reset);
	fprintf(opt->file, "%s%s+++ b/%s%s\n", prefix, c_meta, pair->two->path, c_reset);
	for (i = 0; i < range->ranges.nr; i++) {
		long p_start, p_end;
		long t_start = range->ranges.ranges[i].start;
		long t_end = range->ranges.ranges[i].end;
		long t_cur = t_start;
		int j_last;

		while (j < diff->target.nr && diff->target.ranges[j].end < t_start)
			j++;
		if (j == diff->target.nr || diff->target.ranges[j].start > t_end)
			continue;

		/* Scan ahead to determine the last diff that falls in this range */
		j_last = j;
		while (j_last < diff->target.nr && diff->target.ranges[j_last].start < t_end)
			j_last++;
		if (j_last > j)
			j_last--;

		/*
		 * Compute parent hunk headers: we know that the diff
		 * has the correct line numbers (but not all hunks).
		 * So it suffices to shift the start/end according to
		 * the line numbers of the first/last hunk(s) that
		 * fall in this range.
		 */
		if (t_start < diff->target.ranges[j].start)
			p_start = diff->parent.ranges[j].start - (diff->target.ranges[j].start-t_start);
		else
			p_start = diff->parent.ranges[j].start;
		if (t_end > diff->target.ranges[j_last].end)
			p_end = diff->parent.ranges[j_last].end + (t_end-diff->target.ranges[j_last].end);
		else
			p_end = diff->parent.ranges[j_last].end;

		if (!p_start && !p_end) {
			p_start = -1;
			p_end = -1;
		}

		/* Now output a diff hunk for this range */
		fprintf(opt->file, "%s%s@@ -%ld,%ld +%ld,%ld @@%s\n",
		       prefix, c_frag,
		       p_start+1, p_end-p_start, t_start+1, t_end-t_start,
		       c_reset);
		while (j < diff->target.nr && diff->target.ranges[j].start < t_end) {
			int k;
			for (; t_cur < diff->target.ranges[j].start; t_cur++)
				print_line(prefix, ' ', t_cur, t_ends, pair->two->data,
					   c_context, c_reset, opt->file);
			for (k = diff->parent.ranges[j].start; k < diff->parent.ranges[j].end; k++)
				print_line(prefix, '-', k, p_ends, pair->one->data,
					   c_old, c_reset, opt->file);
			for (; t_cur < diff->target.ranges[j].end && t_cur < t_end; t_cur++)
				print_line(prefix, '+', t_cur, t_ends, pair->two->data,
					   c_new, c_reset, opt->file);
			j++;
		}
		for (; t_cur < t_end; t_cur++)
			print_line(prefix, ' ', t_cur, t_ends, pair->two->data,
				   c_context, c_reset, opt->file);
	}

	free(p_ends);
	free(t_ends);
}

/*
 * NEEDSWORK: manually building a diff here is not the Right
 * Thing(tm).  log -L should be built into the diff pipeline.
 */
static void dump_diff_hacky(struct rev_info *rev, struct line_log_data *range)
{
	fprintf(rev->diffopt.file, "%s\n", output_prefix(&rev->diffopt));
	while (range) {
		dump_diff_hacky_one(rev, range);
		range = range->next;
	}
}

/*
 * Unlike most other functions, this destructively operates on
 * 'range'.
 */
static int process_diff_filepair(struct rev_info *rev,
				 struct diff_filepair *pair,
				 struct line_log_data *range,
				 struct diff_ranges **diff_out)
{
	struct line_log_data *rg = range;
	struct range_set tmp;
	struct diff_ranges diff;
	mmfile_t file_parent, file_target;

	assert(pair->two->path);
	while (rg) {
		assert(rg->path);
		if (!strcmp(rg->path, pair->two->path))
			break;
		rg = rg->next;
	}

	if (!rg)
		return 0;
	if (rg->ranges.nr == 0)
		return 0;

	assert(pair->two->oid_valid);
	diff_populate_filespec(pair->two, 0);
	file_target.ptr = pair->two->data;
	file_target.size = pair->two->size;

	if (pair->one->oid_valid) {
		diff_populate_filespec(pair->one, 0);
		file_parent.ptr = pair->one->data;
		file_parent.size = pair->one->size;
	} else {
		file_parent.ptr = "";
		file_parent.size = 0;
	}

	diff_ranges_init(&diff);
	if (collect_diff(&file_parent, &file_target, &diff))
		die("unable to generate diff for %s", pair->one->path);

	/* NEEDSWORK should apply some heuristics to prevent mismatches */
	free(rg->path);
	rg->path = xstrdup(pair->one->path);

	range_set_init(&tmp, 0);
	range_set_map_across_diff(&tmp, &rg->ranges, &diff, diff_out);
	range_set_release(&rg->ranges);
	range_set_move(&rg->ranges, &tmp);

	diff_ranges_release(&diff);

	return ((*diff_out)->parent.nr > 0);
}

static struct diff_filepair *diff_filepair_dup(struct diff_filepair *pair)
{
	struct diff_filepair *new = xmalloc(sizeof(struct diff_filepair));
	new->one = pair->one;
	new->two = pair->two;
	new->one->count++;
	new->two->count++;
	return new;
}

static void free_diffqueues(int n, struct diff_queue_struct *dq)
{
	int i, j;
	for (i = 0; i < n; i++)
		for (j = 0; j < dq[i].nr; j++)
			diff_free_filepair(dq[i].queue[j]);
	free(dq);
}

static int process_all_files(struct line_log_data **range_out,
			     struct rev_info *rev,
			     struct diff_queue_struct *queue,
			     struct line_log_data *range)
{
	int i, changed = 0;

	*range_out = line_log_data_copy(range);

	for (i = 0; i < queue->nr; i++) {
		struct diff_ranges *pairdiff = NULL;
		struct diff_filepair *pair = queue->queue[i];
		if (process_diff_filepair(rev, pair, *range_out, &pairdiff)) {
			/*
			 * Store away the diff for later output.  We
			 * tuck it in the ranges we got as _input_,
			 * since that's the commit that caused the
			 * diff.
			 *
			 * NEEDSWORK not enough when we get around to
			 * doing something interesting with merges;
			 * currently each invocation on a merge parent
			 * trashes the previous one's diff.
			 *
			 * NEEDSWORK tramples over data structures not owned here
			 */
			struct line_log_data *rg = range;
			changed++;
			while (rg && strcmp(rg->path, pair->two->path))
				rg = rg->next;
			assert(rg);
			rg->pair = diff_filepair_dup(queue->queue[i]);
			memcpy(&rg->diff, pairdiff, sizeof(struct diff_ranges));
		}
		free(pairdiff);
	}

	return changed;
}

int line_log_print(struct rev_info *rev, struct commit *commit)
{
	struct line_log_data *range = lookup_line_range(rev, commit);

	show_log(rev);
	dump_diff_hacky(rev, range);
	return 1;
}

static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *commit,
					  struct line_log_data *range)
{
	struct commit *parent = NULL;
	struct diff_queue_struct queue;
	struct line_log_data *parent_range;
	int changed;

	if (commit->parents)
		parent = commit->parents->item;

	queue_diffs(range, &rev->diffopt, &queue, commit, parent);
	changed = process_all_files(&parent_range, rev, &queue, range);
	if (parent)
		add_line_range(rev, parent, parent_range);
	return changed;
}

static int process_ranges_merge_commit(struct rev_info *rev, struct commit *commit,
				       struct line_log_data *range)
{
	struct diff_queue_struct *diffqueues;
	struct line_log_data **cand;
	struct commit **parents;
	struct commit_list *p;
	int i;
	int nparents = commit_list_count(commit->parents);

	if (nparents > 1 && rev->first_parent_only)
		nparents = 1;

	ALLOC_ARRAY(diffqueues, nparents);
	ALLOC_ARRAY(cand, nparents);
	ALLOC_ARRAY(parents, nparents);

	p = commit->parents;
	for (i = 0; i < nparents; i++) {
		parents[i] = p->item;
		p = p->next;
		queue_diffs(range, &rev->diffopt, &diffqueues[i], commit, parents[i]);
	}

	for (i = 0; i < nparents; i++) {
		int changed;
		cand[i] = NULL;
		changed = process_all_files(&cand[i], rev, &diffqueues[i], range);
		if (!changed) {
			/*
			 * This parent can take all the blame, so we
			 * don't follow any other path in history
			 */
			add_line_range(rev, parents[i], cand[i]);
			clear_commit_line_range(rev, commit);
			commit_list_append(parents[i], &commit->parents);
			free(parents);
			free(cand);
			free_diffqueues(nparents, diffqueues);
			/* NEEDSWORK leaking like a sieve */
			return 0;
		}
	}

	/*
	 * No single parent took the blame.  We add the candidates
	 * from the above loop to the parents.
	 */
	for (i = 0; i < nparents; i++) {
		add_line_range(rev, parents[i], cand[i]);
	}

	clear_commit_line_range(rev, commit);
	free(parents);
	free(cand);
	free_diffqueues(nparents, diffqueues);
	return 1;

	/* NEEDSWORK evil merge detection stuff */
	/* NEEDSWORK leaking like a sieve */
}

static int process_ranges_arbitrary_commit(struct rev_info *rev, struct commit *commit)
{
	struct line_log_data *range = lookup_line_range(rev, commit);
	int changed = 0;

	if (range) {
		if (!commit->parents || !commit->parents->next)
			changed = process_ranges_ordinary_commit(rev, commit, range);
		else
			changed = process_ranges_merge_commit(rev, commit, range);
	}

	if (!changed)
		commit->object.flags |= TREESAME;

	return changed;
}

static enum rewrite_result line_log_rewrite_one(struct rev_info *rev, struct commit **pp)
{
	for (;;) {
		struct commit *p = *pp;
		if (p->parents && p->parents->next)
			return rewrite_one_ok;
		if (p->object.flags & UNINTERESTING)
			return rewrite_one_ok;
		if (!(p->object.flags & TREESAME))
			return rewrite_one_ok;
		if (!p->parents)
			return rewrite_one_noparents;
		*pp = p->parents->item;
	}
}

int line_log_filter(struct rev_info *rev)
{
	struct commit *commit;
	struct commit_list *list = rev->commits;
	struct commit_list *out = NULL, **pp = &out;

	while (list) {
		struct commit_list *to_free = NULL;
		commit = list->item;
		if (process_ranges_arbitrary_commit(rev, commit)) {
			*pp = list;
			pp = &list->next;
		} else
			to_free = list;
		list = list->next;
		free(to_free);
	}
	*pp = NULL;

	for (list = out; list; list = list->next)
		rewrite_parents(rev, list->item, line_log_rewrite_one);

	rev->commits = out;

	return 0;
}
