#!/usr/bin/perl

=head1 NAME

umegaya-adm - A tool to administrate the Umegaya database.

=head1 SYNOPSIS

B<umegaya-adm> B<-p> package B<-k> key B<-v> value [B<--delete] [B<--verbose>]

B<umegaya-adm> B<-h>, B<--help>

=head1 DESCRIPTION

C<umegaya-adm> interrogates or modifies the Berkeley database in which
the gathered metadata is stored. If a combination of package, key and
value is given, it will set the value. Otherwise it will give
appropriate information using the of package or key provided as
argument.

For example:

    $ umegaya-adm -p package -k key -v value
    $ umegaya-adm -p package -k key 
    value
    $ umegaya-adm -p package -k key2 -v value2
    $ umegaya-adm -p package -k key2
    value2
    $ umegaya-adm -p package
    key value
    key2    value2
    $ umegaya-adm -p package2 -k key -v value3
    $ umegaya-adm -k key
    package value
    package2    value3
    $ umegaya-adm -p package2 -k key --delete
    $ umegaya-adm -k key
    package value

=cut 

use strict;
use warnings;

use 5.10.0;

use BerkeleyDB;
use Getopt::Long;
use YAML::AppConfig;

my $conf = YAML::AppConfig->new(file => "/etc/umegaya/umegaya.conf");
my $lib        = $conf->get("db_dir");
my $berkeleydb = $lib . $conf->get("db_name");

my %stored;
umask 002;
tie (%stored, 'BerkeleyDB::Hash', -Filename =>  $berkeleydb, -Flags => DB_CREATE)
    or die "Cannot open file $berkeleydb: $! $BerkeleyDB::Error\n" ;

=head1 OPTIONS

=over 8

=item B<-d>, B<--delete>

In combination with B<--key> or B<--package>, delete the value(s) instead of
displaying them.

=item B<--list-entries>, B<--show-entry>, B<--delete-entry>

List all the entries, or show or delete one entry of the Umegaya database.
These entries are package names joined to a Umegaya key by a colon.  Examples:
“umegaya:Name”, “umegaya:YAML-URL”.

=item B<-k>, B<--key>

If set alone, C<umegaya-adm> will display all the package-values pairs for the
given key. If set together with B<--package>, C<umegaya-adm> will display the
corresponding value.

=item B<-p>, B<--package>

If set alone, C<umegaya-adm> will display all the key-values pairs for the given
package. If set together with B<--key>, C<umegaya-adm> will display the
corresponding value.

=item B<--purge>

Deletes the umegaya database without asking for confirmation.

=item B<-v>, B<--value>

When this option is set together with B<--key> and B<--package>, C<umegaya-adm>
sets the given value for the given key of the given package.

=item B<--verbose>

Returns the set value to the standard output when used in conjunction with
B<--key>, B<--package>, and B<--value>.

=back

=cut

my ($delete, $deleteEntry, $listEntries, $package, $purge, $help, $key, $showEntry, $value, $verbose);

GetOptions (    'delete|d'    => \$delete  ,
                'delete-entry=s'=> \$deleteEntry ,
                'list-entries'=> \$listEntries ,
                'package|p=s' => \$package ,
                'purge'       => \$purge   ,
                'help'        => \$help    ,
                'key=s'       => \$key     ,
                'show-entry=s'=> \$showEntry ,
                'value|v=s'   => \$value   ,
                'verbose'     => \$verbose );

if ($help) {
    print qx(perldoc $0);
    exit;
}

if ($purge) {
    die "$0: --purge can not be combined with other arguments.\n" if ($delete or $listEntries or $package or $key or $value);
    untie %stored;
    unlink $berkeleydb or die "$0: could not remove $berkeleydb: $!\n";
    exit;
}

if ($listEntries) {
    die "$0: --list-entries can not be combined with other arguments.\n" if ($delete or $package or $purge or $key or $value);
    say join "\n", sort keys (%stored);
    exit;
}

if ($showEntry) {
    die "$0: --show-entries can not be combined with other arguments.\n" if ($delete or $package or $purge or $key or $value);
    say $stored{$showEntry} // "Entry not found";
    exit;
}

if ($deleteEntry) {
    die "$0: --show-entries can not be combined with other arguments.\n" if ($delete or $package or $purge or $key or $value);
    delete $stored{$deleteEntry};
    exit;
}

if ($value)        {
    die "$0: --value option needs --package and --key to be set\n" unless ($package and $key);
    $stored{join(':', $package, $key)} = $value;
    say $stored{join(':', $package, $key)} if $verbose; 
} elsif ($key)     {
    if ($package) {
        $delete ? delete $stored{join(':', $package, $key)} : say $stored{join(':', $package, $key)};
        exit
    }
    foreach (keys (%stored)) {
        next unless /:$key$/;
        my $package = (split (':'))[0];
        $delete ? delete $stored{$_} : say $package, "\t", $stored{$_};
    }
} elsif ($package) {
    foreach (keys (%stored)) {
        next unless /^$package:/;
        my $key = (split (':'))[1];
        $delete ? delete $stored{$_} : say $key, "\t", $stored{$_};
    }
} else             {
    die "Use ‘rm $berkeleydb’ to delete the whole file\n" if $delete;
    say "Type umegaya-adm --help to read the documentation";
}

=head1 ADVANCED USAGE

use C<umegaya-adm> to set special keys for the packages.

=head1 SEE ALSO

umegaya(7), upstream-metadata.debian.net(7)

=head1 AUTHOR

Charles Plessy <plessy@debian.org>

=head1 LICENCE

    BOLA - Buena Onda License Agreement (v1.1)
    ------------------------------------------
    
    This work is provided 'as-is', without any express or implied warranty. In no
    event will the authors be held liable for any damages arising from the use of
    this work.
    
    To all effects and purposes, this work is to be considered Public Domain.
    
    
    However, if you want to be "buena onda", you should:
    
    1. Not take credit for it, and give proper recognition to the authors.
    2. Share your modifications, so everybody benefits from them.
    3. Do something nice for the authors.
    4. Help someone who needs it: sign up for some volunteer work or help your
       neighbour paint the house.
    5. Don't waste. Anything, but specially energy that comes from natural
       non-renewable resources. Extra points if you discover or invent something
       to replace them.
    6. Be tolerant. Everything that's good in nature comes from cooperation.

=head1 SOURCE

http://anonscm.debian.org/gitweb/?p=collab-maint/umegaya.git;a=blob;f=scripts/umegaya-adm

=cut
