#!/usr/bin/perl

use DBI;
use RPM::Header;
use Time::HiRes qw/ gettimeofday tv_interval /;
my $nowTime = [gettimeofday];

require "config";

foreach $repo (keys %repo_root) {
    @flist=();
    foreach (@srpm_root) {
        if (($repo eq "orphaned") || ($repo eq "obsolete")) {
            $path=$repo_root{$repo};
	    print "path=$path\n";
        }
	else {
            $path=$repo_root{$repo} . $_;
        }
	if (-d $path) {
	    opendir (DIR,$path) || die "cant open $_\n";
	    @list = sort grep {/\.rpm$/} readdir(DIR);
	    closedir(DIR);
    	    foreach $rpm (@list) {
		    $rpm = $path."/".$rpm;
	    }
	    push @flist, @list;
	}
    }

    @flist = &deleteDup(\@flist);

    print "Begin to extract ". ($#flist+1) . " files\n";

    $dbh = DBI->connect($dsn,$dbUser,$dbPass) || die "cant connect to mysql\n";

    $sth = $dbh->prepare("SELECT name, CONCAT(version,'-',rel) FROM srpm WHERE repo='$repo'");
    $sth->execute();
    $sth2 = $dbh->prepare("REPLACE watch VALUES(?,?,?,?)");
    while (@row = $sth->fetchrow_array){
	$oldS{$row[0]} = $row[1];
    }

    # Sometimes we have broken extract of specs
    # To tell spec2mysql to try extract them again we prepare this list
    if (open (AGAIN, "$tmpdir/again_list") ){
	while (<AGAIN>){
		chomp();
		push @again, $_;
	}
	close(AGAIN);
	unlink("$tmpdir/again_list");
    } else {
	@again = ();
    }

    foreach $rpm (@flist){
	my $hdr =RPM::Header->new($rpm);
	unless ($hdr) {
		next;
	}
	$name = $hdr->{"NAME"};

	if (exists $oldS{$name} &&
		$oldS{$name} eq $hdr->{'VERSION'}."-".$hdr->{'RELEASE'} && (! grep {$name eq $_} @again) ){
		next;
	}
	print "$name with ". ( $#{$hdr->{"PATCH"}}+1 ) . " patches\n";
	
	#SPEC files have flag 32
	for ($i=0;$i<scalar(@{$hdr->{'FILEFLAGS'}});$i++) {
	    $spec = $hdr->{'BASENAMES'}[$i] if (@{$hdr->{'FILEFLAGS'}}[$i] == 32);
	}
	
	$patches = join(" ",@{$hdr->{"PATCH"}}); # if (defined($hdr->{"PATCH"}));
	$sources = "";
	%allsources = ();
	
	for ($i=0;$i<scalar(@{$hdr->{'SOURCE'}});$i++) {
	    for ($j=0;$j<scalar(@{$hdr->{'BASENAMES'}});$j++) {
		# 100Kb - limit of source size
        	if ((@{$hdr->{'SOURCE'}}[$i] eq @{$hdr->{'BASENAMES'}}[$j]) && (@{$hdr->{'SOURCE'}}[$i] ne " ")) {
			if (@{$hdr->{'FILESIZES'}}[$j] < 102400) {
				$allsources{@{$hdr->{'SOURCE'}}[$i]} = "small";
				#Fixme: This is just a temporary stupid hack. Need be rewrited.
				$sources .= @{$hdr->{'SOURCE'}}[$i] . " ";
#				print "source @{$hdr->{'SOURCE'}}[$i] is small\n";
			}
			else {
				$allsources{@{$hdr->{'SOURCE'}}[$i]} = "large";
#				print "source @{$hdr->{'SOURCE'}}[$i] is large\n";
			}
		}
	    }
	}
				    
	print "DEBUG: rpm=$rpm sources=$sources\n\n";
	`cd $tmpdir && rpm2cpio $rpm | cpio -i --quiet $spec $patches $sources`;

	$text = "";
	if ( open(SPEC,$tmpdir."/".$spec) ){
		while(<SPEC>){
			$text .= $_;
			if (/^\%changelog/){
				last;
			}
		}

		$sth = $dbh->prepare("REPLACE spec VALUES(?,?,?)");
		$sth->execute($name,$text,$repo);

		close(SPEC);    
		unlink($tmpdir."/".$spec);
		$num = 0;
		foreach my $patch ( split(/\s/,$patches) ) {
			$out = `file $tmpdir/$patch`;
			if ( $out =~ /gzip\scompressed/ ){
				`cd $tmpdir && gzip -d $patch`;
				$patch =~ s/\.gz$//;
			} elsif ( $out =~ /bzip2\scompressed/ ){
				`cd $tmpdir && bzip2 -d $patch`;
				$patch =~ s/\.bz2$//;
			}
			if ( open(PATCH,$tmpdir."/".$patch) ){
				$text = "";
				while(<PATCH>){
					$text .= $_;
				}
				if (length($text) > 128*1024){
					$text = "Sorry, cannot display patch, because patch size is bigger than 128K.";
				}
				$sth = $dbh->prepare("REPLACE patches VALUES(?,?,?,?,?)");
				$sth->execute($name,$num,$patch,$text,$repo);
				close(PATCH);
				unlink($tmpdir."/".$patch);
				$text = "";
			} else {
				print "cannot open patch: $patch\n";
			}
			$num++;
		}
		$num = 0;
#		print ("source = $sources\n");
		foreach $source (keys %allsources)  {
#			print "SOURCE= $source\n";
			$text = "";
			if ($allsources{$source} eq "small") {
				if ( open(SOURCE,$tmpdir."/".$source) ){
			    		while(<SOURCE>){
						$text .= $_;
			    		}
			    		close(SOURCE);
			    		unlink($tmpdir."/".$source);
				} else {
			    		print "cannot open source: $source\n";
				}
			}
			else {
				$text = "Source is too large.\n";
			}
			$sth = $dbh->prepare("REPLACE sources VALUES(?,?,?,?,?)");
			$sth->execute($name,$num,$source,$text,$repo);
			$num++;
		}
	} else {
		print "can't open spec: $spec\n";
	}
    }
    $sth2->finish();
    $dbh->disconnect();

    print "\nTime elapsed: ";
    print tv_interval ($nowTime);
    print "\n";
}
