#!/usr/bin/perl
#
#  buildstatus : Check on the build status of all target packages
#  Copyright (C) 2007  Neil Williams <codehelp@debian.org>
#
#  This package 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 3 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 Cwd;
use Config::Auto;
use File::Basename;
use Emdebian::Tools;
use Text::FormatTable;
use Debian::DpkgCross;
use Term::ANSIColor qw(:constants);
use strict;
use warnings;
use vars qw($our_version $home $dpkg_cross_dir $msg $verbose $workdir $progname );

$our_version = &tools_version;
$verbose = 1;
$progname = basename($0);
&read_config();
my $arch = &get_architecture();
$dpkg_cross_dir = &get_dpkg_cross_dir;

sub usageversion {
    print(STDERR <<END)
buildstatus version $our_version

Usage:
 buildstatus [-a|--arch ARCH] [-v|--verbose] [-q|--quiet]
 buildstatus -h|--help|--version

Options:
 -a|--arch ARCH:      set architecture (default: defined by dpkg-cross)
 -v|--verbose:        be verbose (repeat for more verbosity)
 -q|--quiet:          be quiet [default]
 -h|--help:           print this usage message and exit
 --version:           print this usage message and exit

User-specific configuration values in ~/.apt-cross/emsource,
override any debconf default in /etc/emsource.conf. If no
preferred working directory is set, buildstatus checks current
working directory.

END
        || die "$0: failed to write usage: $!\n";
exit 0;
}

while( @ARGV ) {
	$_= shift( @ARGV );
	last if m/^--$/;
	if (!/^-/) {
		unshift(@ARGV,$_);
		last;
	}
	elsif (/^(-h|--help|--version)$/) {
		&usageversion();
		exit( 0 );
	}
	elsif (/^(-v|--verbose)$/) {
		$verbose++;
	}
	elsif (/^(-q|--quiet)$/) {
		$verbose--;
	}
	elsif (/^(-a|--arch)$/) {
		$arch = shift(@ARGV);
	}
	else {
		die RED, "$progname: Unknown option $_.", RESET, "\n";
	}
}

my $quiet = "";
$quiet = "-q" if ($verbose < 1);

$msg = "$progname: please install 'subversion' before using $progname.\n";
warn RED, $msg, RESET if (! -x "/usr/bin/svn");

$workdir = &get_workdir;
$workdir = "." if ($workdir eq "");
$msg = &check_workdir($workdir);
die $msg if ($msg ne "");
chdir ("$workdir/trunk") if ($workdir ne ".");
print "Working directory: '" . cwd . "'\n" if ($verbose >= 2);

my @alpha = qw/a b c d e f g h i j k l m n o p q r s t u v w x y z/;
my $table = Text::FormatTable->new('24l 20l 18l 18l 18l 20l');
$table->head("Package", "#Patches", "Build", "pbuild", ".changes", "uploaded");
$table->rule('=');
my %complete = ();
foreach my $a (@alpha)
{
	opendir (DH, "$a/") or warn ("Cannot read directory $a: $!.\n");
	my @list = grep(!/^\.\.?$|^\.svn$/, readdir DH);
	closedir(DH);
	foreach my $one (@list)
	{
		opendir (DH, "$a/$one/trunk")
			or die ("Cannot read subdirectory $a/$one/trunk: $!\n");
		my @contents = grep(!/^\.\.?$|^\.svn$/, readdir DH);
		closedir (DH);
		$complete{$one} = \@contents;
	}
}
my $count = 0;
my $logs = 0;
foreach my $pkg (sort keys %complete)
{
	my $files = $complete{$pkg}; # get value
	my ($indexchar)=split(//, $pkg);
	my $patch = 0;
	my $build = "";
	my $pbuild = "";
	my $changes = "";
	my $uploads = "";
	my $emver = "";
	foreach my $f (@$files)
	{
		$emver = "";
		$patch++ if ($f =~ /^emdebian.*\.patch$/);
		$patch++ if ($f =~ /^debian-patch.*\.patch$/);
		if ($f =~ /_(.*)_${arch}\.build/)
		{
			$emver = $1;
			$build .= "\n$emver";
		}
		if ((-f "../pbuilder/result/$indexchar/$pkg/trunk/${pkg}_${emver}_$arch.build")
			and ($f =~ /_${emver}_${arch}\.build/))
		{
			$pbuild .= "\n$emver" if (-f "../pbuilder/result/$indexchar/$pkg/trunk/${pkg}_${emver}_$arch.changes");
		}
		if ($f =~ /_(.*)_.*\.changes/)
		{
			$changes .= "\n$1";
		}
		if ($f =~ /\.upload$/)
		{
			$f =~ /_(.*)_${arch}\.upload$/;
			my @about = stat "$indexchar/$pkg/trunk/$f";
			# read the ctime of the .upload file
			$uploads = " $1\n" . scalar localtime($about[10]);
		}
	}
	my $cell1 = ($patch > 0) ? "$patch patches" : "" ;
	my $cell2 = "$build";
	my $cell3 = "$changes";
	my $cell4 = "$uploads";
	$table->row("$pkg ", $cell1, $cell2, $pbuild, $cell3, $cell4);
	$count++;
	if ($count % 15 == 0)
	{
		$table->rule('=');
		$table->head("Package", "#Patches", "Build", "pbuild", ".changes", "uploaded");
		$table->rule('=');
	}
	else
	{
		$table->rule('-');
	}
}
open (SP, "| sensible-pager");
print SP "Checking the status of all target packages in SVN\n";
print SP "Using sensible-pager, use 'q' to exit\n\n";
print SP $table->render(20);
print SP "$count packages identified.\n";
close (SP);
