#!/usr/bin/perl

use DBI;
use RPM::Header;
use Time::HiRes qw/ gettimeofday tv_interval /;
use lib "/home/liks/scripts";
use upstreamwatch;
my $nowTime = [gettimeofday];

require "config";

my $upstreamwatch = new upstreamwatch;

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){
	unless (tie %hdr, "RPM::Header", $rpm ) {
		next;
	}
	$name = $hdr{"NAME"};

	if (exists $oldS{$name} &&
		$oldS{$name} eq $hdr{'VERSION'}."-".$hdr{'RELEASE'} && (! grep {$name eq $_} @again) ){
		untie %hdr;
		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";
			}
		}
	    }
	}
				    
	untie %hdr;
	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 (($source eq ($name . ".watch")) || ($source eq "watch")) {
			    print "source=watch\n";
			    ($url,$version) = upstreamwatch::watchfileprocess($tmpdir."/".$source);
			    print "url=$url version=$version source=$source \n";
			    if ($url) {
				$version="3" if !($version);
				$sth2->execute($name,$url,$version,"altwatch");
			    }
			}
			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";
}
