#!/usr/bin/perl -w
#
# Retrieves the current list of Policy bugs awaiting review and produces a
# formatted list suitable for mailing out, requesting review.
#
# Eventually, the goal is for this script to be expanded into one that can
# give a summary for all open Policy bugs for a periodic automated report.
#
# The SOAP code here is based heavily on Devscripts::Debbugs.
#
# Originally written by Russ Allbery.  Enhanced to handle usertags by
# Sean Whitton.

use strict;

use SOAP::Lite ();
use List::MoreUtils qw(first_index);
use Array::Utils qw(intersect);

# The URL to the SOAP interface for the Debian BTS interface and the SOAP
# namespace used by that interface.
our $URL       = 'https://bugs.debian.org/cgi-bin/soap.cgi';
our $NAMESPACE = 'Debbugs/SOAP/1';

# Abort if we get a SOAP error.  This function is used as the error handler
# for our SOAP calls.
sub die_soap {
    my ($soap, $result) = @_;
    my $error;
    if (ref $result) {
        $error = $result->faultstring;
    } else {
        $error = $soap->transport->status;
    }
    chomp $error;
    die "SOAP error: $error\n";
}

# Initialize the SOAP::Lite object with the correct URL and namespace and
# return it.
sub init_soap {
    my $soap = SOAP::Lite->uri ($NAMESPACE)->proxy ($URL);
    $soap->transport->env_proxy;
    $soap->on_fault (\&die_soap);
}

# Do a SOAP search for bugs following a particular provided criteria
# (as key/value pairs) and print out a summary of all such bugs.
# Criteria are conjoined, but there is known bug with this when more
# than one 'usertag' criteria is specified
sub print_bug_list {
    my ($soap, @criteria) = @_;
    unshift (@criteria, status => 'open');
    unshift (@criteria, package => 'debian-policy');
    # the soap interface separates fetching bugs by usertag and
    # fetching bugs by all other criteria, so we have to filter out
    # 'usertag' and handle it differently
    my @usertags;
    while (my $usertag_index = first_index { $_ eq 'usertag' } @criteria) {
        last if $usertag_index < 0;
        push @usertags, $criteria[$usertag_index + 1];
        # now we have the usertag, drop it from the criteria fed to the
        # non-usertag SOAP interface
        splice @criteria, $usertag_index, 2;
    }
    my $bugs;
    if (@usertags) {
        my @usertag_bugs;
        my $usertag_bugs_hash = $soap->
          get_usertag ('debian-policy@packages.debian.org', @usertags)->result;
        foreach my $key (keys %$usertag_bugs_hash) {
            my @value = @{$usertag_bugs_hash->{$key}};
            if (scalar @usertag_bugs < 1) {
                @usertag_bugs = @value;
            } else {
                @usertag_bugs = intersect (@usertag_bugs, @value);
            }
        }
        my $all_bugs = $soap->get_bugs (@criteria)->result;
        my @bugs = intersect (@usertag_bugs, @$all_bugs);
        $bugs = \@bugs;
    } else {
        $bugs = $soap->get_bugs (@criteria)->result;
    }
    unless (@$bugs) {
        print "No bugs found\n";
        return;
    }
    my $info = $soap->get_status (@$bugs)->result;
    for my $bug (sort keys %$info) {
        my $desc = $info->{$bug}{subject};
        $desc =~ s/^debian-policy:\s+//;
        if (length ($desc) > 70) {
            $desc = substr ($desc, 0, 67) . '...';
        }
        print "#$bug $desc\n";
    }
}

# Main routine.
my $soap = init_soap;
print "Consensus has been reached and help is needed to write a patch:\n\n";
print_bug_list ($soap, usertag => 'proposal');
print "\nWording proposed, awaiting review from anyone and/or seconds by DDs:\n\n";
print_bug_list ($soap, tag => 'patch');
print "\nMerged for the next release:\n\n";
print_bug_list ($soap, tag => 'pending');
