#!/usr/bin/perl
#
# wanna-build-statistics: print statistics for wanna-build databases
# Copyright © 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
#
# 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, see
# <http://www.gnu.org/licenses/>.
#
#######################################################################

use strict;
use vars qw($verbose $dist $database);

sub percent (@);
sub isin ($@);

$verbose = 0;
$dist = "unstable";
$database = "build-db";

while( @ARGV && $ARGV[0] =~ /^-/ ) {
    $_ = shift @ARGV;
    if (/^-v$/ || /^--verbose$/) {
	$verbose++;
    }
    elsif (/^-d/ || /^--dist/) {
	if (/^-d(.)/ || /^--dist=(.)/) {
	    $dist = $1.$';
	}
	elsif (!@ARGV) {
	    die "$_ option missing argument\n";
	}
	else {
	    $dist = shift @ARGV;
	}
	$dist = "stable"   if $dist eq "s";
	$dist = "testing"  if $dist eq "t";
	$dist = "unstable" if $dist eq "u";
	die "Bad distribution\n" if !isin($dist, qw(stable testing unstable stable-security testing-security));
    }
    elsif (/^--$/) {
	last;
    }
    elsif (/^--database=(.*)$/) {
	$database = $1;
    }
    else {
	die "Unknown option: $_\n";
    }
}

my($lastmsg, %n_state, $total, %n_builder);
open( PIPE, "wanna-build --database=$database --dist=$dist --list=all 2>&1 |" )
    or die "Cannot spawn wanna-build: $!\n";
while( <PIPE> ) {
    if (/^Database for $dist doesn't exist$/) {
	exit 1;
    }
    elsif (/^Total (\d+) package\(s\) in state (\S+)\.$/) {
	$n_state{$2} = $1;
    }
    elsif (/^Total (\d+) package\(s\)$/) {
	$total = $1;
    }
    elsif (/^\S+: (\S+) by (\S+)/) {
	$n_builder{$1}->{$2}++;
    }
    $lastmsg = $_;
}
close( PIPE );
if ($?) {
    print "$lastmsg";
    die "Bad exit status $? from wanna-build\n";
}

print "Distribution $dist:\n";
print "--------------", "-" x length($dist), "\n";

my $total_width = 78;
my @state_list = qw(Installed Needs-Build Building Uploaded Failed Dep-Wait
					Failed-Removed Dep-Wait-Removed
					Not-For-Us);
my $statewidth = 0;
grep { $statewidth = length($_) if length($_) > $statewidth } @state_list;
my $startcol = $statewidth + 9;

my($state, $builder);
foreach $state (@state_list) {
    printf "%-${statewidth}s: %5d", $state, $n_state{$state};
    if (!keys %{$n_builder{$state}}) {
	print "\n";
	next;
    }
    my $sum = 0;
    foreach $builder (keys %{$n_builder{$state}}) {
	$sum += $n_builder{$state}->{$builder};
    }
    $n_builder{$state}->{"unknown"} = $n_state{$state} - $sum;
    print " (";
    my $is_first = 1;
    my $pos = $startcol;
    foreach $builder (sort keys %{$n_builder{$state}}) {
	next if !$n_builder{$state}->{$builder};
	my $str = "$builder: $n_builder{$state}->{$builder}";
	$str = ", $str" if !$is_first;
	$is_first = 0;
	if ($pos + length($str) > $total_width) {
	    print ",\n", " " x $startcol;
	    $pos = $startcol;
	    $str =~ s/^, //;
	}
	print $str;
	$pos += length($str);
    }
    print ")\n";
}
printf "%-${statewidth}s: %5d\n", "total", $total;
print "\n";

$total -= $n_state{"Not-For-Us"};
print percent(qw(Installed)), " up-to-date, ";
print percent(qw(Installed Uploaded)), " if also counting uploaded pkgs\n";
print percent(qw(Needs-Build)), " uncompiled\n";
print percent(qw(Building)), " currently building (short-term delay)\n";
print percent(qw(Failed Dep-Wait)), " failed or waiting (long-term delay)\n";

exit 0;

sub percent (@) {
    my $n = 0;
    foreach (@_) {
	$n += $n_state{$_};
    }

    return sprintf "%6.2f%%", $n*100/$total if $total;
    return sprintf "%6.2f%%", 0;
}

sub isin ($@) {
    my $val = shift;
    return grep( $_ eq $val, @_ );
}
