#!/usr/bin/perl -w

use strict;
use DBI;
use XML::Simple;
use File::Find;

my $dbh;
my $sth_insert_depmap;
my $sth_insert_dep;
my $sth_insert_pom;
my $sth_test;

my $pkgkey=$ENV{'REPOCOP_PKG_KEY'};
my $pkgname=$ENV{'REPOCOP_PKG_NAME'};
my $REPOCOP_PKG_ROOT=$ENV{'REPOCOP_PKG_ROOT'};
my $db_tested=0;

if (-d $REPOCOP_PKG_ROOT.'/etc/maven/fragments' or 
    -d $REPOCOP_PKG_ROOT.'/usr/share/maven-fragments') {
#=====deptest=========
    &db_test();
    my $xml='<opt>';
    foreach my $xmlfile (glob $REPOCOP_PKG_ROOT."{/etc/maven/fragments,/usr/share/maven-fragments}/*" ) {
	next unless -e $xmlfile;
	open my $fh, "<", $xmlfile or die $!;
	local $/; # enable localized slurp mode
	my $content = <$fh>;
	$xml.=$content;
	close $fh;
    }
    $xml.='</opt>';
    my $pom=XML::Simple->new()->XMLin($xml,ForceArray => [ 'dependency' ]);
    my $depsptr=$pom->{'dependency'};
    foreach my $dep (@$depsptr) {
	my $maven=$dep->{'maven'};
	my $jpp=$dep->{'jpp'};
	$sth_insert_depmap->execute(
	    $pkgkey,
	    $maven->{'groupId'},
	    $maven->{'artifactId'},
	    $maven->{'version'},
	    $jpp->{'groupId'},
	    $jpp->{'artifactId'},
	    $jpp->{'version'},
	    );
    }
}
#=====end-deptest=========

my @dirs_to_search=grep { -d $_} map {$REPOCOP_PKG_ROOT.$_} qw!
/usr/share/maven-poms/
/usr/share/maven2/poms/
/usr/share/maven2/default_poms/
!;
exit 0 unless @dirs_to_search>0;

find(\&wanted, @dirs_to_search);
sub wanted {
    return unless /\.pom$/;
    #return if (-l $_);
    my $pomfile=$_;
    my $filename=$File::Find::name;
    $filename=~s/^$ENV{'REPOCOP_PKG_ROOT'}//;
    #print $filename,":\n";
    &db_test();
    #=====pomtest=========

    my $pom=XML::Simple->new()->XMLin($pomfile,ForceArray => [ 'dependency' ]);
    my $groupId=$pom->{'groupId'};
    my $artifactId=$pom->{'artifactId'};
    my $version=$pom->{'version'};
    my $parent=$pom->{'parent'};
    if ($parent) {
	$groupId||=$parent->{'groupId'};
	$artifactId||=$parent->{'artifactId'};
	$version||=$parent->{'version'};
    }
    my $error_message;
    if ($pom->{pomVersion}) {
	$error_message="Outdated pom version.";
    } elsif (! $pom->{'modelVersion'}) {
	$error_message="pom is invalid (modelVersion not found).";
    } elsif ($pom->{'modelVersion'} ne '4.0.0' and $pom->{'modelVersion'} ne '5.0.0') {
	$error_message="pom has unsupported version.";
    } elsif (!(defined $groupId && defined $artifactId)) {
	$error_message="pom does not have required keys.";
    }
    if ($error_message) {
	system('repocop-test-warn', "$filename: $error_message");
    } else {
	if (! defined $version) {
	    $version='';
	    system('repocop-test-experimental', "$filename: pom version is not defined.");
	}
	$sth_insert_pom->execute($pkgkey,$filename,
				 $groupId,
				 $artifactId,
				 $version,
	    );

	#my $dmref=$pom->{'dependencyManagement'};
	my $depsref=$pom->{'dependencies'};
	if ($depsref) {
	    my $depsptr=$depsref->{'dependency'};
	    foreach my $dep (@$depsptr) {
		#'version' => '${pom.version}',
		#'groupId' => '${pom.groupId}',
		my $dep_groupId=$dep->{'groupId'};
		my $dep_artifactId=$dep->{'artifactId'};
		my $dep_version=$dep->{'version'};
		my $dep_optional=$dep->{'optional'};
		my $dep_scope=$dep->{'scope'};
		my $dep_type=$dep->{'type'};
		$dep_version = $version if $dep_version and ($dep_version eq '${project.version}' or $dep_version eq '${pom.version}' or $dep_version eq '${version}');
		$dep_groupId = $groupId if $dep_groupId and ($dep_groupId eq '${project.groupId}' or $dep_groupId eq '${pom.groupId}' or $dep_groupId eq '${groupId}');
		$dep_version = '' unless defined $dep_version;
		$dep_scope ||= 'compile';
		$dep_type = '' unless defined $dep_type;
		$sth_insert_dep->execute($pkgkey,$filename,
					 $dep_groupId,
					 $dep->{'artifactId'},
					 $dep_version,
					 $dep_scope,
					 $dep_type,
		    ) if ! $dep_optional;
	    }

	}
    }
};


&disconnect();

sub db_test {
    return if $db_tested;
    &connect();
    $sth_test->execute($pkgkey);
    my @row = $sth_test->fetchrow_array;
    if (@row>0) {
	# remove pkgid from db;
	$dbh->do("DELETE FROM pom WHERE pkgid='$pkgkey'");
	$dbh->do("DELETE FROM pom_depmap WHERE pkgid='$pkgkey'");
	$dbh->do("DELETE FROM pom_dependencies WHERE pkgid='$pkgkey'");
    }
    $db_tested=1;
}

sub connect {
    my $dbfile=$ENV{'REPOCOP_TEST_DB'};
    die "database is not initialized properly!" unless $dbfile;
    $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile","","", {
	PrintError => 1,
	AutoCommit => 0,
			}) or die $dbh->errstr;
    $sth_test=$dbh->prepare('SELECT PKGID FROM pom WHERE PKGID=? LIMIT 1') or die $dbh->errstr;
    $sth_insert_depmap=$dbh->prepare('INSERT INTO pom_depmap VALUES(?,?,?,?,?,?,?)') or die $dbh->errstr;
    $sth_insert_dep=$dbh->prepare('INSERT INTO pom_dependencies VALUES(?,?,?,?,?,?,?)') or die $dbh->errstr;
    $sth_insert_pom=$dbh->prepare('INSERT INTO pom VALUES(?,?,?,?,?)') or die $dbh->errstr;
}

sub disconnect {
    $dbh->commit;
    $sth_insert_depmap->finish;
    $sth_insert_dep->finish;
    $sth_insert_pom->finish;
    # hack around closing dbh with active statement handles bug
    local $SIG{'__WARN__'} = sub {};
    $dbh->disconnect;
}

