#!/usr/bin/perl

use strict;
use warnings;

use Cwd;
use File::Basename;
use Getopt::Long;
use Pod::Usage;

use DistroMap 0.09;
use RPM::Source::Editor 0.766;
use RPM::Source::Transform;
use RPM::Source::Tools::PackageFilter;
use RPM::Source::Tools::BuildReqStorage;
use RPM::Source::Tools::SourceBundle;
use RPM::Source::Tools::SourceAnalyzer;
$DistroMap::Repository::opt_check_distrodb=7; # days
my $branch='sisyphus';
my $verbose=0;
my ($specfile,$update,$help,$rpmbuild_bp);
my $spec;
my @IN;

my $result = GetOptions (
    @RPM::Source::Tools::SourceAnalyzer::LONGOPT,
    @DistroMap::Repository::LONGOPT,
    'b|branch=s' => \$branch,
    'bp' => \$rpmbuild_bp,
    'spec=s'   => \$specfile,
    'help=s'   => \$help,
    'verbose+' => \$verbose,
    'q|quiet'  => sub {$verbose=0},
    'h|help'   => \$help,
    'update'   => \$update,
    );
$specfile=shift @ARGV if $ARGV[0] and $ARGV[0] =~ /\.spec$/;
if ($help or (not @ARGV and not ($specfile and $rpmbuild_bp))) {
    my $man_verbose=$verbose+1;
    system("pod2usage --exit=0 --verbose $man_verbose $0");
    print "\n";
    &DistroMap::Repository::longopt_usage();
    print "\n";
    &RPM::Source::Tools::SourceAnalyzer::longopt_usage();
    exit (1);
}

push @IN, @ARGV;
if (defined $specfile and -e $specfile) {
    $spec=RPM::Source::Editor->new(
	SPECFILE=>$specfile,
	);
    my $name=$spec->main_section->get_tag('Name');
    $RPM::Source::Tools::SourceAnalyzer::opt_hint='octave' if $name =~ /^octave-/ and not $RPM::Source::Tools::SourceAnalyzer::opt_hint;
    if ($rpmbuild_bp) {
	my $builddir=$spec->macros->macro_subst('%_builddir');
	die "Oops! can't find \%_builddir" unless $builddir;
	system('rm','-rf',$builddir);
	system('rpmbuild','-bp','--nodeps',$specfile)==0 or die "Oops! rpmbuild -bp --nodeps $specfile failed\n";
	unshift @IN, $builddir;
    }
}

my $distro_sisyphus=DistroMap::Repository->new(-repo=>'altlinux', -branch=>$branch);
my $buildreq=RPM::Source::Tools::BuildReqStorage->new(
    -ignore => {map {$_=>1} qw/glibc-devel/},
);
my ($existing,$existing_pre,$old,$old_pre)=$buildreq->current_buildreq($spec);
my $analyzer=RPM::Source::Tools::SourceAnalyzer->new(
    -verbose => $verbose,
    -buildreq_storage=>$buildreq,
    -distroinfo => $distro_sisyphus,
    -current_buildreq => $existing,
    );

map {&analyze($_)} @IN;
warn "WARNING: input is empty (neither source tarballs or source directories are specified, nor -bp option is used.\n" if not @IN;
my $nodep_msg=$spec ? "buildreq-src: $specfile already contains all found dependencies\n" : 
    "buildreq-src: nothing found.\n";
if ($update and $spec) {
    my $entry=$buildreq->get_entry($existing,$existing_pre);
    print $entry ? $entry : $nodep_msg;
    if ($entry or scalar %$old or scalar %$old_pre) {
	$buildreq->update_spec_entry($spec);
	$spec->write_spec($specfile);
	print STDERR "buildreq-src: updated $specfile\n";
    } else {
	print STDERR "buildreq-src: no need to update $specfile\n";
    }
} else {
    my $entry=$buildreq->get_entry($existing,$existing_pre);
    print $entry ? $entry : $nodep_msg;
}

sub analyze {
    my ($file)=@_;
    print STDERR '=== processing ',$file,"\n" if $verbose;
    my $bundle=RPM::Source::Tools::SourceBundle->create($file);
    $analyzer->analyze($bundle);
}

__END__

=head1	NAME

buildreq-src - a tool to deduce the Build Environment from Source files.

=head1	SYNOPSIS

B<buildreq-src>
[B<-h,--help>] 
[B<-v, --verbose>]
[B<-b> I<branch>]
[[B<-s,--spec>] I<specfile>]
I<dir...> | I<tarball ...>

=head1	DESCRIPTION

buildreq-src is a tool to deduce the Build Environment from Source files.

=head1	OPTIONS

=over

=item	B<-h, --help>

Display this help and exit.

=item	B<-v, --verbose>, B<-q, --quiet>

Verbosity level. Multiple -v increase the verbosity level, -q sets it to 0.
Default is 1.

=item	B<-s, --spec> I<specfile>

Output directory.

=item	B<-bp> 

Execute rpmbuild -bp --nodeps on the spec file and add %_builddir to the list
of sources to analyze.

=item	B<--update> 

Update BuildRequires in given spec file.

=item	B<--sourcedep-*> 

Options that start with B<--sourcedep-*> are SourceAnalyzer specific options.
For current list of the options and their meaning run this program with --help.

=back

=head1	AUTHOR

Written by Igor Vlasenko <viy@altlinux.org>.

=head1	COPYING

Copyright (c) 2008 Igor Vlasenko, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=cut
