#!/usr/bin/env perl

use feature say;
use strict;
use Debian::Debhelper::Buildsystem::R qw(parse_deps);
use Dpkg::Control;
use Dpkg::Deps qw(deps_parse);
use Getopt::Long;
use Pod::Usage;

my $opt_desc = 0;
my $opt_help = 0;

GetOptions('help|?' => \$opt_help, 'desc|d' => \$opt_desc);
pod2usage(1) if $opt_help;

( -d "debian") or die "No debian/ directory, this tool updates existing R packaging";
( -e "DESCRIPTION") or die "No DESCRIPTION file, is this an R package?";

my $desc = Dpkg::Control->new(type => Dpkg::Control::CTRL_UNKNOWN);
$desc->load("DESCRIPTION");

my $dctrl = Dpkg::Control::Info->new();
$dctrl->load("debian/control");

my $dsrc = $dctrl->get_source();
my $dbin = $dctrl->get_pkg_by_idx(1);

my @aptavail = qx/grep-aptavail -P -s Package -n -e ^r-/;
my %apthash;
@apthash{@aptavail} = ();

sub deps_concat {
    # Dpkg::Deps::deps_concat generates "dep, , , " if some arguments are empty strings
    my (@dep_list) = @_;
    @dep_list = grep { /[a-z]/ } @dep_list;
    return join ', ', @dep_list;
}

sub unmanaged {
    my $rawtext = shift;
    # deps_parse errors on substvars like ${R:Depends}, so split it manually
    my @deps = split(/\s*,\s*/m, $rawtext);
    my @keep;
    foreach my $d (@deps) {
        if ($d !~ /^(r-|debhelper|dh-r|\$)/) {
            say "I: keeping unmanaged dependency: $d";
            push(@keep, $d);
        }
    }
    return deps_concat(@keep);
}

say "I: Updating Build-Depends";
my $unmanaged_builddeps = unmanaged($dsrc->{'Build-Depends'});
my $rdepends = deps_concat(Debian::Debhelper::Buildsystem::R::parse_depends("Depends", $desc->{Depends}, \%apthash));
my $rimports = deps_concat(Debian::Debhelper::Buildsystem::R::parse_depends("Imports", $desc->{Imports}, \%apthash));
my $compiled = lc $desc->{NeedsCompilation} eq "yes";
$dsrc->{'Build-Depends'} = deps_concat("debhelper (>= 10)", "dh-r", "r-base-dev", $rdepends, $rimports, $unmanaged_builddeps);

say "I: Updating binary Depends, Recommends, Suggests";
my $unmanaged_depends = unmanaged($dbin->{Depends});
my $unmanaged_recommends = unmanaged($dbin->{Recommends});
my $unmanaged_suggests = unmanaged($dbin->{Suggests});
$dbin->{Depends} = deps_concat("\${R:Depends}", $compiled ? "\${shlibs:Depends}" : "", "\${misc:Depends}", $unmanaged_depends);
$dbin->{Recommends} = deps_concat("\${R:Recommends}", $unmanaged_recommends);
$dbin->{Suggests} = deps_concat("\${R:Suggests}", $unmanaged_suggests);

if ( ! -e 'debian/tests/control' & ! exists $dsrc->{Testsuite} ) {
    say "W: No debian/tests/control and no Testsuite field, adding Testsuite: autopkgtest-pkg-r";
    $dsrc->{Testsuite} = "autopkgtest-pkg-r";
}

if ($opt_desc) {
    say "I: Updating package description";
    my $longdesc = $desc->{Description};
    $longdesc =~ s/^\s*//gm;
    $dbin->{Description} = "$desc->{Title}\n$longdesc";
}

open(my $fh, ">", "debian/control") or die "Can't write to debian/control";
$dctrl->output($fh);
close($fh);

__END__

=head1 NAME

dh-update-R - Updates d/control for a debian R package

=head1 SYNOPSIS

dh-update-R [options]

 Options:
    --help
    --desc Update the package description

=head1 OPTIONS

=over 8

=item B<--help>

Print this help message.

=back

=head1 DESCRIPTION

B<dh-update-R> should be run from the root of an unpacked R tarball (ie, the
directory containing DESCRIPTION), where there is already a debian/ directory.
This tools attempts to update files in debian/ after a new upstream version has
been imported.
