#!/usr/bin/perl -w

use strict;
use File::Temp;
use Getopt::Long;

Getopt::Long::Configure ('no_ignore_case');

my $dir = File::Temp::tempdir ( CLEANUP => 1 );
my ($fh, $filename) = File::Temp::tempfile ( DIR => $dir );

my @rpm_sections = qw/description prep build install clean pre preun post postun triggerin triggerun triggerpostun files changelog/;
my %rpm_sections;
foreach (@rpm_sections) {
	$rpm_sections{$_} = 1;
}

my @protocols = qw/ftp http https/;
my $protocols_re = '(?:' . join ('|', @protocols) . ')';

my @defines;
my %sources;
my %patches;
my $specfile;
my $verbose = 0;
my $dummy = 0;

sub eval_sources_patches {
	print $fh
"Summary: foo
Name: foo
Version: foo
Release: foo
License: FOO!
Group: Foo
\%description
\%prep
echo BEGIN
";

	foreach (@defines) {
		print $fh "\%define $_\n";
	}

	print $fh "cat << EOF_$filename\n";

	while (<>) {
		my $line = $_;
		if ($line =~ m/^\s*%(\w+)/) {
			my $word = lc $1;
			if (defined ($rpm_sections{$word})) {
				last;
			}
		}
		print $fh $line;
	}

	print $fh "EOF_$filename";
	close $fh;

	open PIPE, "rpmbuild -bp $filename 2>/dev/null |" or die;

	while (<PIPE>) {
		chomp ();
		if (m/^\s*(source|patch)(\d*)\s*:\s*(.*\S)\s*$/i) {
			my $what = \%sources;
			if ($1 eq 'patch') {
				$what = \%patches;
			}
			my $index = 0;
			if ($2 ne '') {
				$index = $2;
			}
			$what->{$index} = $3;
		}
	}

	close PIPE;
}

sub expand {
	my $foo = $_[0];
	my @retval;
	foreach ($foo) {
		m/^sources$/i && do {
			foreach (sort (keys %sources)) {
				$retval[$#retval + 1] = "source$_";
			}
		};

		m/^patches$/i && do {
			foreach (sort (keys %patches)) {
				$retval[$#retval + 1] = "patch$_";
			}
		};
		m/^all$/i && do {
			@retval = (expand ('sources'), expand ('patches'));
		};
	}
	return @retval;
}

sub list_sources_patches {
	foreach (@_) {
		m/^source(\d+)$/i && print "Source$1: " . $sources{$1} . "\n";
		m/^patch(\d+)$/i && print "Patch$1: " . $patches{$1} . "\n";
		m/^(sources|patches|all)$/i && list_sources_patches (expand ($1));
	}
}

sub retrievable {
	my $url = $_[0];
	return eval "\$url =~ m,^$protocols_re://,;";
}

sub retrieve {
	my $url = $_[0];
	if (retrievable ($url)) {
		print "Getting $url\n" if ($verbose);
		print "--> wget $url\n" if ($verbose > 1);
		system ("wget $url") unless ($dummy);
	} else {
		print STDERR "Couldn't fetch $url: missing URL\n" if ($verbose);
	}
}

sub retrieve_sources_patches {
	foreach (@_) {
		m/^source(\d+)$/i && retrieve ($sources{$1});
		m/^patch(\d+)$/i && retrieve ($patches{$1});
		m/^(sources|patches|all)$/i && retrieve_sources_patches (expand ($1));
	}
}

# main

my $command = 'retrieve';

GetOptions ('d|define=s' => \@defines,
            'l|list' => sub { $command = 'list'; },
			'v|verbose' => sub { $verbose++; },
			'D|dummy' => sub { $dummy = 1; });

$specfile = $ARGV[0];

my @what = @ARGV[1..$#ARGV];
if ($#what < 0) {
	@what = ('all');
}

eval_sources_patches ();
foreach ($command) {
	m/list/ && list_sources_patches (@what);
	m/retrieve/ && retrieve_sources_patches (@what);
}
