#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use File::Basename;
use Emdebian::Grip;
use POSIX qw(locale_h);
use Locale::gettext;
use Debian::Packages::Compare;
use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
use vars qw/ $prog $our_version $filter_name $grip_name $locale_name
 $suite $base $single @archlist @components @locroots %binaries
 %griplist %localelist %filterlist %updates $pkg %sources %except
 $simulate $mirror %package %list $fh $arch /;
$prog = basename($0);
$our_version = &scripts_version();
setlocale(LC_MESSAGES, "");
textdomain("emdebian-grip");
$filter_name = 'filter';
$locale_name = "locale";
$mirror = "http://ftp.uk.debian.org/debian";
$grip_name = 'grip';
$suite = "unstable";
$base = '/opt/reprepro/';
$except{'balloon3-config'}++;
$except{'grip-config'}++;
while( @ARGV ) {
	$_= shift( @ARGV );
	last if m/^--$/;
	if (!/^-/) {
		unshift(@ARGV,$_);
		last;
	}
	elsif (/^(-\?|-h|--help|--version)$/) {
		&usageversion();
		exit (0);
	}
	elsif (/^(-b|--base-path)$/) {
		$base = shift;
	}
	elsif (/^(-s|--suite)$/) {
		$suite = shift;
	}
	elsif (/^(--filter-name)$/) {
		$filter_name = shift;
	}
	elsif (/^(-M|--mirror)$/) {
		$mirror = shift;
	}
	elsif (/^(--grip-name)$/) {
		$grip_name = shift;
	}
	elsif (/^(-n|--simulate)$/) {
		$simulate++;
	}
	else {
		die "$prog: "._g("Unknown option")." $_.\n";
	}
}
$base .= '/' if ("$base" !~ m:/$:);
if (not -d $base) {
	printf (_g("ERR: Please specify an existing directory for the base-path: %s\n"), $base);
	exit 1;
}
&set_base($base);
&set_repo_names ($filter_name, $grip_name);
my $a = &get_archlist ($suite, $filter_name);
die (_g("unable to get architecture list\n")) if (not defined $a);
@archlist = @$a;
my $l = &get_locale_roots ($suite, 'locale');
die (_g("unable to get locale rootfs list\n")) if (not defined $l);
@locroots = @$l;

my $debf    = &get_debian($suite);
my $gripf   = &read_packages ($suite, $grip_name);
my $locf    = &read_locale   ($suite, $locale_name);
my $debs;
if ($suite eq "stable") {
	$debs    = &get_debian ("stable-proposed-updates");
}
%filterlist = %$debf  if (defined $debf);
%griplist   = %$gripf if (defined $gripf);
%localelist = %$locf  if (defined $locf);
%updates    = %$debs  if (defined $debs);
foreach $pkg (sort keys %griplist) {
	next if (exists $filterlist{$pkg});
	next if (($suite eq "stable") and (exists $updates{$pkg}));
	next if (exists $except{$pkg});
	$sources{$pkg}++ if ($pkg eq $griplist{$pkg}{'Src'});
	$binaries{$pkg}++;
}
foreach my $src (sort keys %sources) {
	if (defined $simulate) {
		print "reprepro -v -b ${base}grip removesrc $suite $src\n";
		print "reprepro -v -b ${base}filter removesrc $suite $src\n";
		print "reprepro -v -b ${base}locale removesrc $suite $src\n";
	} else {
		system ("reprepro -v -b ${base}grip removesrc $suite $src");
		system ("reprepro -v -b ${base}filter removesrc $suite $src");
		system ("reprepro -v -b ${base}locale removesrc $suite $src");
	}
}
foreach my $bin (sort keys %binaries) {
	if (defined $simulate) {
		print "reprepro -v -b ${base}grip remove $suite $bin\n";
		print "reprepro -v -b ${base}filter remove $suite $bin\n";
	} else {
		system ("reprepro -v -b ${base}grip remove $suite $bin");
		system ("reprepro -v -b ${base}filter remove $suite $bin");
	}
}

exit 0;

sub get_debian {
	return undef unless defined $base;
	mkdir ("${base}debianbase") if (not -d "${base}debianbase");
	chdir ("${base}debianbase");
	my ($suite) = shift;
	system ("wget $mirror/dists/$suite/main/source/Sources.gz");
	my $input = "Sources.gz";
	my $z = new IO::Uncompress::Gunzip $input
		or die "IO::Uncompress::Gunzip failed: $GunzipError\n";
	my $parser = Parse::Debian::Packages->new( $z );
	while (%package = $parser->next)
	{
		$list{$package{'Package'}}{'source'}=$package{'Version'};
		my $src = (not defined $package{'Source'}) ?
			$package{'Package'} :
			$package{'Source'};
		$src =~ s/\(.*\)//g;
		$src =~ s/ //g;
		$list{$package{'Package'}}{'Src'}=$src;
		my $dep = $package{'Build-Depends'};
		chomp ($dep) if (defined $dep);
		$list{$package{'Package'}}{'Build-Depends'}=$dep;
	}
	unlink $input;
	foreach $arch (@archlist) {
		next if ($arch eq "source");
		next if ($arch eq "sh4");
		system ("wget $mirror/dists/$suite/main/binary-$arch/Packages.gz");
		my $file = "Packages.gz";
		next unless (-f $file);
		my $z = new IO::Uncompress::Gunzip $file
			or die "IO::Uncompress::Gunzip failed: $GunzipError\n";
		$parser = Parse::Debian::Packages->new( $z );
		while (%package = $parser->next)
		{
			$list{$package{'Package'}}{"$arch"}=$package{'Version'};
			my $src = (not defined $package{'Source'}) ?
				$package{'Package'} :
				$package{'Source'};
			$src =~ s/\(.*\)//g;
			$src =~ s/ //g;
			$list{$package{'Package'}}{'Src'}=$src
				if (not defined $list{$package{'Package'}}{'Src'});
		}
		unlink $file;
	}
	return \%list;
}

sub usageversion
{
	printf(STDERR (_g("
%s - handle removals from Debian
version %s

Syntax: %s -b PATH [OPTIONS]
        %s -?|-h|--help|--version

Commands:
-b|--base-path PATH:           path to the top level grip directory [required]
-?|-h|--help|--version:        print this help message and exit

Options:
-n|--dry-run:                  check which packages would be processed
-s|--suite:                    check a suite other than unstable
-n|--simulate:                 simulate changes only
-M|--mirror MIRROR:            use a different Debian mirror for updates
                                [default: http://ftp.uk.debian.org/debian]
   --filter-name STRING:       alternative name for the filter repository
   --grip-name STRING:         alternative name for the grip repository

"), $prog, $our_version, $prog, $prog, $prog))
	or die ("$0: "._g("failed to write usage").": $!\n");
}
