package DiffHighlight;

use 5.008;
use warnings FATAL => 'all';
use strict;

# Use the correct value for both UNIX and Windows (/dev/null vs nul)
use File::Spec;

my $NULL = File::Spec->devnull();

# Highlight by reversing foreground and background. You could do
# other things like bold or underline if you prefer.
my @OLD_HIGHLIGHT = (
	color_config('color.diff-highlight.oldnormal'),
	color_config('color.diff-highlight.oldhighlight', "\x1b[7m"),
	color_config('color.diff-highlight.oldreset', "\x1b[27m")
);
my @NEW_HIGHLIGHT = (
	color_config('color.diff-highlight.newnormal', $OLD_HIGHLIGHT[0]),
	color_config('color.diff-highlight.newhighlight', $OLD_HIGHLIGHT[1]),
	color_config('color.diff-highlight.newreset', $OLD_HIGHLIGHT[2])
);

my $RESET = "\x1b[m";
my $COLOR = qr/\x1b\[[0-9;]*m/;
my $BORING = qr/$COLOR|\s/;

my @removed;
my @added;
my $in_hunk;
my $graph_indent = 0;

our $line_cb = sub { print @_ };
our $flush_cb = sub { local $| = 1 };

# Count the visible width of a string, excluding any terminal color sequences.
sub visible_width {
	local $_ = shift;
	my $ret = 0;
	while (length) {
		if (s/^$COLOR//) {
			# skip colors
		} elsif (s/^.//) {
			$ret++;
		}
	}
	return $ret;
}

# Return a substring of $str, omitting $len visible characters from the
# beginning, where terminal color sequences do not count as visible.
sub visible_substr {
	my ($str, $len) = @_;
	while ($len > 0) {
		if ($str =~ s/^$COLOR//) {
			next
		}
		$str =~ s/^.//;
		$len--;
	}
	return $str;
}

sub handle_line {
	my $orig = shift;
	local $_ = $orig;

	# match a graph line that begins a commit
	if (/^(?:$COLOR?\|$COLOR?[ ])* # zero or more leading "|" with space
	         $COLOR?\*$COLOR?[ ]   # a "*" with its trailing space
	      (?:$COLOR?\|$COLOR?[ ])* # zero or more trailing "|"
	                         [ ]*  # trailing whitespace for merges
	    /x) {
	        my $graph_prefix = $&;

		# We must flush before setting graph indent, since the
		# new commit may be indented differently from what we
		# queued.
		flush();
		$graph_indent = visible_width($graph_prefix);

	} elsif ($graph_indent) {
		if (length($_) < $graph_indent) {
			$graph_indent = 0;
		} else {
			$_ = visible_substr($_, $graph_indent);
		}
	}

	if (!$in_hunk) {
		$line_cb->($orig);
		$in_hunk = /^$COLOR*\@\@ /;
	}
	elsif (/^$COLOR*-/) {
		push @removed, $orig;
	}
	elsif (/^$COLOR*\+/) {
		push @added, $orig;
	}
	else {
		flush();
		$line_cb->($orig);
		$in_hunk = /^$COLOR*[\@ ]/;
	}

	# Most of the time there is enough output to keep things streaming,
	# but for something like "git log -Sfoo", you can get one early
	# commit and then many seconds of nothing. We want to show
	# that one commit as soon as possible.
	#
	# Since we can receive arbitrary input, there's no optimal
	# place to flush. Flushing on a blank line is a heuristic that
	# happens to match git-log output.
	if (!length) {
		$flush_cb->();
	}
}

sub flush {
	# Flush any queued hunk (this can happen when there is no trailing
	# context in the final diff of the input).
	show_hunk(\@removed, \@added);
	@removed = ();
	@added = ();
}

sub highlight_stdin {
	while (<STDIN>) {
		handle_line($_);
	}
	flush();
}

# Ideally we would feed the default as a human-readable color to
# git-config as the fallback value. But diff-highlight does
# not otherwise depend on git at all, and there are reports
# of it being used in other settings. Let's handle our own
# fallback, which means we will work even if git can't be run.
sub color_config {
	my ($key, $default) = @_;
	my $s = `git config --get-color $key 2>$NULL`;
	return length($s) ? $s : $default;
}

sub show_hunk {
	my ($a, $b) = @_;

	# If one side is empty, then there is nothing to compare or highlight.
	if (!@$a || !@$b) {
		$line_cb->(@$a, @$b);
		return;
	}

	# If we have mismatched numbers of lines on each side, we could try to
	# be clever and match up similar lines. But for now we are simple and
	# stupid, and only handle multi-line hunks that remove and add the same
	# number of lines.
	if (@$a != @$b) {
		$line_cb->(@$a, @$b);
		return;
	}

	my @queue;
	for (my $i = 0; $i < @$a; $i++) {
		my ($rm, $add) = highlight_pair($a->[$i], $b->[$i]);
		$line_cb->($rm);
		push @queue, $add;
	}
	$line_cb->(@queue);
}

sub highlight_pair {
	my @a = split_line(shift);
	my @b = split_line(shift);

	# Find common prefix, taking care to skip any ansi
	# color codes.
	my $seen_plusminus;
	my ($pa, $pb) = (0, 0);
	while ($pa < @a && $pb < @b) {
		if ($a[$pa] =~ /$COLOR/) {
			$pa++;
		}
		elsif ($b[$pb] =~ /$COLOR/) {
			$pb++;
		}
		elsif ($a[$pa] eq $b[$pb]) {
			$pa++;
			$pb++;
		}
		elsif (!$seen_plusminus && $a[$pa] eq '-' && $b[$pb] eq '+') {
			$seen_plusminus = 1;
			$pa++;
			$pb++;
		}
		else {
			last;
		}
	}

	# Find common suffix, ignoring colors.
	my ($sa, $sb) = ($#a, $#b);
	while ($sa >= $pa && $sb >= $pb) {
		if ($a[$sa] =~ /$COLOR/) {
			$sa--;
		}
		elsif ($b[$sb] =~ /$COLOR/) {
			$sb--;
		}
		elsif ($a[$sa] eq $b[$sb]) {
			$sa--;
			$sb--;
		}
		else {
			last;
		}
	}

	if (is_pair_interesting(\@a, $pa, $sa, \@b, $pb, $sb)) {
		return highlight_line(\@a, $pa, $sa, \@OLD_HIGHLIGHT),
		       highlight_line(\@b, $pb, $sb, \@NEW_HIGHLIGHT);
	}
	else {
		return join('', @a),
		       join('', @b);
	}
}

# we split either by $COLOR or by character. This has the side effect of
# leaving in graph cruft. It works because the graph cruft does not contain "-"
# or "+"
sub split_line {
	local $_ = shift;
	return utf8::decode($_) ?
		map { utf8::encode($_); $_ }
			map { /$COLOR/ ? $_ : (split //) }
			split /($COLOR+)/ :
		map { /$COLOR/ ? $_ : (split //) }
		split /($COLOR+)/;
}

sub highlight_line {
	my ($line, $prefix, $suffix, $theme) = @_;

	my $start = join('', @{$line}[0..($prefix-1)]);
	my $mid = join('', @{$line}[$prefix..$suffix]);
	my $end = join('', @{$line}[($suffix+1)..$#$line]);

	# If we have a "normal" color specified, then take over the whole line.
	# Otherwise, we try to just manipulate the highlighted bits.
	if (defined $theme->[0]) {
		s/$COLOR//g for ($start, $mid, $end);
		chomp $end;
		return join('',
			$theme->[0], $start, $RESET,
			$theme->[1], $mid, $RESET,
			$theme->[0], $end, $RESET,
			"\n"
		);
	} else {
		return join('',
			$start,
			$theme->[1], $mid, $theme->[2],
			$end
		);
	}
}

# Pairs are interesting to highlight only if we are going to end up
# highlighting a subset (i.e., not the whole line). Otherwise, the highlighting
# is just useless noise. We can detect this by finding either a matching prefix
# or suffix (disregarding boring bits like whitespace and colorization).
sub is_pair_interesting {
	my ($a, $pa, $sa, $b, $pb, $sb) = @_;
	my $prefix_a = join('', @$a[0..($pa-1)]);
	my $prefix_b = join('', @$b[0..($pb-1)]);
	my $suffix_a = join('', @$a[($sa+1)..$#$a]);
	my $suffix_b = join('', @$b[($sb+1)..$#$b]);

	return visible_substr($prefix_a, $graph_indent) !~ /^$COLOR*-$BORING*$/ ||
	       visible_substr($prefix_b, $graph_indent) !~ /^$COLOR*\+$BORING*$/ ||
	       $suffix_a !~ /^$BORING*$/ ||
	       $suffix_b !~ /^$BORING*$/;
}
