#!/usr/bin/perl

use strict;
use warnings;

use Getopt::Long;
use Pod::Usage;
use MDV::Repsys;
use MDV::Repsys::Remote;
use POSIX qw(getcwd);
use File::Temp qw(tempdir);

=head1 NAME

mdvsys

=head1 DESCRIPTION

Tools to import and extract rpm from a svn

=head1 SYNOPSIS

mdvsys [options] <action> ...

<action> is one of:

=over 4

=item import rpmfile1 [[rpmfile2] ...]

import one or more src.rpm directly into the svn.

=item getsrpm pkgname

Extract a source package from the svn into current directory.

=item checkout pkgname [dir]

Checkout from svn the "current" version of a package.

=item sync [dir]

Find the spec file into the dir SPECS/ and perform proper add/del on
sources file into the svn from a working copy.

No changes are done into the repository.

=item build pkgname

Retrieve from svn and build package "pkgname"

=item stripcl [specfile]

Remove the changelog of the specfile and commit it into the svn.

If the --no-commit options is set, the commit part is not done.

=back

=cut

my %roptions;

=head1 OPTIONS

=over 4

=item -v

Increase verbosity level.

=item -c <configfile>

Use this configuration file instead /etc/repsys.conf.

=item no-commit

Commit into the svn will not be done.

This options has effect for import action.

=item r <revision>

Work on a specific revision.

=item m <message>

Set this message for commiting

=item noyouri

Get the standard srpms file, without the '@rev:' prefix.

=back

=cut

GetOptions(
    'no-commit'  => \my $nocommit,
    'm=s'        => \$roptions{commit_message},
    'r=s'        => \$roptions{revision},
    'c|config=s' => \my $configfile,
    'd|dest=s'   => \$roptions{destdir},
    'noyouri'    => \my $noyouri,
    'v+'         => \my $verbosity,
) or pod2usage(1);

my ($action, @args) = @ARGV;

if (!$action) {
    pod2usage(0);
}

my $exitstatus = 0;

MDV::Repsys::set_verbosity($verbosity);

for ($action) {

    /^sync$/ and do {
        my $dir = $args[0] || getcwd();
        my $spec = (glob("$dir/SPECS/*.spec"))[0];
        if ($spec) {
            MDV::Repsys::set_rpm_dirs($dir);
            if (! MDV::Repsys::sync_source(
                $dir,
                (glob("$dir/SPECS/*.spec"))[0],
            )) {
                warn "Can't sync $dir:\n";
                warn MDV::Repsys::repsys_error() ."\n";
                $exitstatus = 1;
            }
        } else {
            warn "Can't find any specfile\n";
            $exitstatus = 1;
        }
        last;
    };

    my $repsys = MDV::Repsys::Remote->new(
        nocommit => $nocommit,
        configfile => $configfile,
    );
    $repsys->set_verbosity($verbosity);

    /^import$/ and do {
        foreach my $rpmfile (@args) {
            if (!$repsys->import_pkg(
                $rpmfile,
                %roptions,
            )) {
                warn $repsys->last_error() . "\n";
                warn "Can't import $rpmfile\n";
                $exitstatus = 1;
            }
        }
        last;
    };

    /^getsrpm$/ and do {
        foreach my $name (@args) {
            my ($r, $f) = $repsys->get_srpm(
                $name,
                %roptions,
            );
            if ($r) {
                if ($noyouri) {
                    print "$r $f\n";
                } else {
                    my $ysrpms = sprintf(
                        '@%d:%s',
                        $r, ($f =~ m:.*/+(.*\.src.rpm)$:)[0]
                    );
                    system('mv', $f, $ysrpms);
                    print "$ysrpms\n";
                }
            } else {
                warn $repsys->last_error() . "\n";
                warn "Can't extract $name\n";
                $exitstatus = 1;
            }
        }
        last;
    };

    /^(co|checkout)$/ and do {
        if (!$repsys->checkout_pkg(
            $args[0],
            $args[1],
            %roptions,
        )) {
            warn $repsys->last_error() . "\n";
            warn "Can't checkout $args[0]\n";
            $exitstatus = 1;
        }
        last;
    };

    /^log$/ and do {
        if (!$repsys->build_final_changelog($args[0])) {
            warn $repsys->last_error() . "\n";
            warn "Can't get changelog of $args[0]\n";
            $exitstatus = 1;
        }
        last;
    };

    /^tag$/ and do {
        if (!$repsys->tag_pkg(
            $args[0],
            %roptions,
        )) {
            warn $repsys->last_error() . "\n";
            warn "Can't tag $args[0]\n";
            $exitstatus = 1;
        }
        last;
    };

    /^build$/ and do {
        my $bdir;
        my $specfile;
        if ($args[0]) {
            $bdir = tempdir();
            $repsys->checkout_pkg(
                $args[0],
                $bdir,
                 %roptions,
            ) or do {
                warn $repsys->last_error() . "\n";
                warn "Can't extract $args[0]\n";
                $exitstatus = 1;
                next;
            };
            $specfile = $repsys->get_final_spec(
                (glob("$bdir/SPECS/*.spec"))[0],
                %roptions, pkgname => $args[0],
            ) or do {
                warn $repsys->last_error() . "\n";
                warn "can't get final specfile\n";
                $exitstatus = 1;
                next;
            };
        } else {
            $bdir = getcwd();
        }
        RPM4::setverbosity('INFO');
        MDV::Repsys::build(
            $bdir,
            'b',
            %roptions, specfile => $specfile,
        ) or do {
            warn MDV::Repsys::repsys_error() . "\n";
            warn "Build failed\n";
            $exitstatus = 1;
        };
        RPM4::setverbosity('WARNING');
        last;
    };

    /^stripcl$/ and do {
        my $specfile = $args[0] || (glob("SPECS/*.spec"))[0];
        if (! ($nocommit ?
            MDV::Repsys::strip_changelog($specfile) :
            $repsys->splitchangelog($specfile))) {
            warn $repsys->last_error() . "\n";
            warn "Can't extract changelog";
            $exitstatus = 1;
        }
        last;
    };

    pod2usage(1);
}

exit($exitstatus);

__END__

=head1 AUTHORS

Olivier Thauvin <nanardon@mandriva.org>

=head1 SEE ALSO

L<repsys>

=cut
