#!/usr/bin/perl -w
# Extract the packages from the available releases by
# taking a look at the Packages.gz files
#
# Javier Fernandez-Sanguino Peņa <jfs_at_debian.org>
# Distributed under the GNU GPL

use strict;
use Getopt::Std;
# Options:
# -d = debug
# -m dir     = use mirror directory 'dir'
# -a arch    = use architecture 'arch'

getopts('dp:r:m:a:');
use vars qw/$opt_d $opt_p $opt_r $opt_m $opt_a/;

# Variables
my $pwd = `pwd`;
chomp $pwd;

# Debug
my $debug       = $opt_d || 0;
# Releases and path location 
my $mirrordir   = $opt_m || "/home/mirrors/debian/debian.org";
my $arch        = $opt_a || "i386";

#my @components =  ("main", "contrib", "non-free") ;
# We are only interested in main or contrib, since non-free is not 
# 'supported'
my @components =  ("main", "contrib");
my @releases = ( );
my %releaseh;
my %sections;
my %priorities;
my %packages;
find_releases($mirrordir."/dists");
print "Found the following releases in $mirrordir: @releases\n";

foreach my $releasei (0 .. $#releases ) {
	my $release = $releases[$releasei];
	foreach my $componenti (0 .. $#components ) {
		my $component = $components[$componenti];
		my $Packages =$mirrordir."/dists/".$release."/".$component."/binary-".$arch."/Packages.gz";
		if ( -e $Packages ) { 
			$releaseh{$release}{$component}=$Packages; 
			print "Found component '$component' for release '$release' at $releaseh{$release}{$component}\n" if $debug;
		}
	}
}


# For each release read all the files and make a *Big* hash

foreach my $releasei (0 .. $#releases ) {
	my $release = $releases[$releasei];
	foreach my $file ( keys(%{$releaseh{$release}}) ) {
		read_file($release,$releaseh{$release}{$file});
	}
}

# Once this is done symlink all package names for all releases

foreach my $releasei (0 .. $#releases ) {
	my $release = $releases[$releasei];
	print "Data for release: $release\n";
	print "Section, packages\n";
	print "-----------------\n";
	foreach my $section ( keys(%{$sections{$release}}) ) {
		print "$section, $sections{$release}{$section}\n";
	}
	print "Priority, packages\n";
	print "-----------------\n";
	foreach my $priority ( keys(%{$priorities{$release}}) ) {
		print "$priority, $priorities{$release}{$priority}\n";
	}
	print "----------------------------------------------------------\n";
} # of the foreach

# The other way around (currelease vs prevrelease)

exit 0;

sub retrieve_version {
# Retrieves the version info from the text
	my ($text)=@_;
	print "Extracting version from $text\n" if $debug;
	my $retversion="unknown";
	if ( $text =~ /^.*{(.*?)}$/ ){
		$retversion=$1;
	} 
	return $retversion;
}
sub retrieve_text {
# Retrieves the description info from the text
	my ($origtext)=@_;
	print "Extracting text from $origtext\n" if $debug;
	my $rettext="";
	if ( $origtext =~ /^(.*){.*?}$/ ){
		$rettext=$1;
	} 
	return $rettext;
}

sub read_file {
# Read in a Package file and retrieves packages for a given release
	my ($release,$file)=@_;

	open (FILE,"zcat $file |") || die ("Cannot open $file: $!");
	print "Reading $file\n" if $debug;
# Finite-state machine
# 0 - no package
# 1 - package name read
# 2 - version read
# 3 - package description read
	my $state=0;
	my $packagename="";
	my $priority="";
	my $section="";
	my $version="";
	while (<FILE>) {
		chomp;
		if ( $state == 4 && /^$/ ){
			$packages{$release}{$packagename}=$version;
			print "Found $packagename: ($version) in section $section, priority $priority\n" if $debug;
			$sections{$release}{$section}++;
			$priorities{$release}{$priority}++;
			$state=0;
		}
		if ( /^$/ && $state > 0  ){
# Package that does not comply the state-machine
			$state=0;
		}
		if ( $state == 1 && /^Priority: (.*)$/ ){
			$priority=$1;
			$state=2;
		}
		if ( $state == 2 && /^Section: (.*)$/ ){
			$section=$1;
			$state=3;
		}
		if ( $state == 3 && /^Version: (.*)$/ ){
			$version=$1;
			$state=4;
		}
		if ( $state == 0 && /^Package: (.*)$/ ){
			$packagename=$1;
			$state=1;
		}
	}
	close FILE;

}

sub find_releases {
# Find the releases available in the mirror
	my ($mirror) = @_;
	opendir (MIRROR, "$mirror") || die "Could not open mirror dir $mirror: $!";
	while ( my $entry = readdir(MIRROR) ) {
		next if $entry =~ /^\./ ;
		my $fullname = $mirror."/".$entry;
		print STDERR "Checking $fullname\n" if $opt_d;
		# Skip symbolic links
		next if ( -l $fullname );
		if ( -d $fullname) {
			push @releases, $entry;
		}
	}
	close MIRROR;
	return 0;
}

