#!/usr/bin/perl

# Copyright © 2019 Felix Lechner
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, you can find it on the World Wide
# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301, USA.

# The harness for Lintian's test suite.  For detailed information on
# the test suite layout and naming conventions, see t/tests/README.
# For more information about running tests, see
# doc/tutorial/Lintian/Tutorial/TestSuite.pod
#

use v5.20;
use warnings;
use utf8;
use autodie;

# use Lintian modules that belong to this program
use FindBin;
use lib "$FindBin::RealBin/../lib";

use Cwd;
use Capture::Tiny qw(capture_merged);
use Getopt::Long;
use List::Util qw(all);
use Path::Tiny;
use Term::ANSIColor;

use Test::Lintian::Output::Universal qw(parse_line order);

use constant EMPTY => q{};
use constant SPACE => q{ };
use constant COLON => q{:};
use constant LPARENS => q{(};
use constant RPARENS => q{)};
use constant NEWLINE => qq{\n};

# options
my $interactive;

Getopt::Long::Configure;
unless (
    Getopt::Long::GetOptions(
        'i|interactive'  => \$interactive,
        'help|h'         => sub {usage(); exit;},
    )
) {
    usage();
    die;
}

# check arguments and options
die "Please use -h for usage information.\n"
  if scalar @ARGV != 2;

# get arguments
my ($diffpath, $tagspath) = @ARGV;

my @difflines = path($diffpath)->lines_utf8;
chomp @difflines;

my @tagslines = path($tagspath)->lines_utf8;
chomp @tagslines;

my $changed;

foreach my $line (@difflines) {
    my ($sign, $stripped) = $line =~ qr/^([+-])(.*)$/;

    die "$diffpath is not a tagdiff file"
      unless length $sign && defined $stripped;

    if ($interactive) {

        my $command;
        my $color;

        if ($sign eq '+') {
            $command = 'Add';
            $color = 'bold bright_white on_green';
        } else {
            $command = 'Remove';
            $color = 'bold bright_white on_red';
        }

        my $colored = $stripped;
        $colored = colored($stripped, $color)
          if -t STDOUT;
        print "$colored - $command (y/n/q)? ";

        my $decision = <STDIN>;
        chomp $decision;
        exit if $decision eq 'q';
        next unless $decision eq 'y';
    }

    if ($sign eq '+') {
        # say "Adding: $stripped";
        push(@tagslines, $stripped);
    } else {
        # say "Removing: $stripped";
        # remove the first match only
        my $found = 0;
        @tagslines = grep {$_ ne $stripped || $found++} @tagslines;
    }

    $changed = 1;
}

exit unless $changed;

# also sort output into preferred order
my $joined = EMPTY;
$joined .= $_ . NEWLINE
  for reverse sort { order($a) cmp order($b) } @tagslines;
path($tagspath)->spew_utf8($joined);

exit;

sub usage {
    print <<"END";
Usage: $0 -i <tagdiff-file> <tags-file>

    --interactive, -i  Apply <tagdiff-file> interactively

    Applies <tagdiff-file> to <tagsfile> so that the new file represents the
    changes. Please use tagdiff to create the file with the changes.

    The tags are then sorted in the order preferred for universal tags.
END
    return;
}

# Local Variables:
# indent-tabs-mode: nil
# cperl-indent-level: 4
# End:
# vim: syntax=perl sw=4 sts=4 sr et
