#!/usr/bin/perl -w

# parse setup.ini into data structure
local $/;   # slurp
my $setupini = <>;
my $packages = parse_ini(\$setupini);

# add all packages in base
foreach my $pack (keys %$packages) {
  addpack($packages, $pack, "") if (grep(/^base$/i, @{ $packages->{$pack}->{'category'} }));
}

#my $mirror = "";
#my $mirror = "http://mirrors.rcn.net/pub/sourceware/cygwin/";
my $mirror = "http://mirrors.kernel.org/sourceware/cygwin/";

my $totsize = 0;
foreach my $pack (sort keys %$packages) {
  if ($packages->{$pack}->{'needed'}) {
    if (!defined($packages->{$pack}->{'curr'})) {
      print STDERR "Warning: possibly bogus package $pack\n";
      next;
    }
    $totsize += $packages->{$pack}->{'curr'}->{'size'};
    print $mirror . $packages->{$pack}->{'curr'}->{'file'} . "\n";
  }
}

printf "# total size: $totsize (%.1fM)\n", ($totsize / (1024**2));
 
sub addpack
# input: a reference to the parsed setup.ini, a package name, name of the package that's requiring this one
# function: selects $pack and all its dependencies
{
  my ($p, $pack, $neededby) = @_;
 
  return if($pack =~ /^_/ || exists($p->{$pack}->{'needed'}));
  $p->{$pack}->{'needed'} = 1;
  if($ENV{'DEBUG'}) {
    print STDERR "Adding $pack" . (length($neededby) ? " (needed by $neededby)\n" : " (in Base)\n");
  }
  addpack($p, $_, $pack) foreach (@{ $p->{$pack}->{'requires'} });
}    

sub parse_ini
# input: a reference to the contents of setup.ini
# returns: a hashref containing the parsed structure
{
  my $s = shift;
  my $p = {};
  my $id = 1;
  
  # el ghetto parser
  while( $$s =~ m/\n@ ([^\s]+)\n/g ) {
    my $pack = $1;
    my $vers = 'curr';
    $p->{$pack} = {};
    $p->{$pack}->{'vers'} = {};
    $p->{$pack}->{'id'} = $id++;
    
    LOOP: {
      $p->{$pack}->{'sdesc'} = $1, redo LOOP if( $$s =~ m/\Gsdesc: *\"([^"]*)\"\n/igc );
      $p->{$pack}->{'ldesc'} = $1, redo LOOP if( $$s =~ m/\Gldesc: *\"([^"]*)\"\n/igcs );
      $p->{$pack}->{'category'} = [ split(/ +/, $1) ], redo LOOP if( $$s =~ m/\Gcategory: *(.*)\n/igc );
      $p->{$pack}->{'requires'} = [ split(/ +/, $1) ], redo LOOP if( $$s =~ m/\Grequires: *(.*)\n/igc );
      $p->{$pack}->{$vers}->{'vers'} = $1,
        $p->{$pack}->{$vers}->{'file'} = $2,
        $p->{$pack}->{$vers}->{'size'} = $3,
        redo LOOP if( $$s =~ m/\Gversion: *(.*)\ninstall: (\S+) (\d+)[^\n]+\n(source: [^\n]+\n)?/igc );
      $vers = 'prev', redo LOOP if( $$s =~ m/\G\[prev\]\n/igc );
      $vers = 'test', redo LOOP if( $$s =~ m/\G\[test\]\n/igc );
    }
    if(!exists($p->{$pack}->{'sdesc'})
       || !exists($p->{$pack}->{'category'})
     # || scalar keys %{$p->{$pack}->{'vers'}} < 1   # some packages have no version ?!?  eg. gcc-gm2
       ) {
      print STDERR "Warning: package $pack missing some fields.\n";
    }
  }
  
  return $p;
}
 