#!/usr/bin/env perl

use lib qw(); # PERL5LIB
use FindBin; use lib "$FindBin::Bin/../lib", "$FindBin::Bin/../thirdparty/lib/perl5"; # LIBDIR

use Getopt::Long qw(:config posix_default no_ignore_case);
use Pod::Usage;

use Mojo::Base -strict;
use ZnapZend::Config;
use ZnapZend::ZFS;
my $VERSION = '0.dev'; #VERSION
my $zConfig;
my $zZfs;
my $zTime = ZnapZend::Time->new();

sub dumpStats {
    my $stats = shift;
    my $tabs = shift;

    if (! $tabs) {
       print ' ' x (5 - length($stats->{usage}));
    }
    print $stats->{usage};
    print ($tabs ? "\t" : "   ");
    print "$stats->{last_snap}";
    print ($tabs ? "\t" : "   ");
    print "$stats->{dataset}\n";
}

sub collectData {
    my $dataset = shift;
    my $snapFilter = shift;
    my %data;
    my $snapshots = $zZfs->listSnapshots($dataset, $snapFilter);

    $data{usage} = $zZfs->usedBySnapshots($dataset);
    my $lastSnap = $snapshots->[-1] // ' @No Snapshots Yet  ';
    ($data{last_snap}) = $lastSnap =~ /^.+\@([^\@]+)$/;
    $data{dataset} = $dataset;

    return \%data;
}

sub main {
    my $opts = {};

    GetOptions($opts, qw(H help|h recursive|r only-enabled pfexec sudo rootExec=s man timeWarp=i)) or exit 1;

    if ($opts->{pfexec}) {
        warn "--pfexec is deprecated. Use --rootExec=pfexec instead\n";
        $opts->{rootExec} = 'pfexec';
    } elsif ($opts->{sudo}) {
        warn "--sudo is deprecated. Use --rootExec=sudo instead\n";
        $opts->{rootExec} = 'sudo';
    }

    $zZfs = ZnapZend::ZFS->new(rootExec => $opts->{rootExec});
    $zConfig = ZnapZend::Config->new(rootExec => $opts->{rootExec}, timeWarp=> $opts->{timeWarp});

    $opts->{help} && do {
        pod2usage(-exitval => 'NOEXIT');

### RM_COMM_4_TEST ###  # remove ### RM_COMM_4_TEST ### comments for testing purpose.
### RM_COMM_4_TEST ###  $opts = {};

        return 1;
    };
    $opts->{man} && pod2usage(-exitstatus => 0, -verbose => 2);

    # MAYBE make $enabledOnly parameter public in Config.pm
    my $backupSets = ($opts->{"only-enabled"} ? $zConfig->getBackupSetEnabled(pop @ARGV) : $zConfig->getBackupSet(pop @ARGV))
        or die "ERROR: cannot list backup config\n";

    #check if there is at least one valid backup set
    @$backupSets or die "ERROR: no valid znapzend setup found on source\n";

    my $dummyTime = $zTime->createSnapshotTime(time + ($opts->{timeWarp} // 0), $backupSets->[0]->{tsformat});

    #print header
    print 'USED    LAST SNAPSHOT' . ' ' x (24 - length($dummyTime))
        . "DATASET\n" if !$opts->{H};

    for my $backupSet (@$backupSets){
        my $datasets = $backupSet->{recursive} eq 'on' && $opts->{recursive}
            ? $zZfs->listSubDataSets($backupSet->{src}) : [$backupSet->{src}];

        my $snapFilter = $zTime->getSnapshotFilter($backupSet->{tsformat});

        #source dataset
        for my $dataset (@$datasets){
            dumpStats(collectData($dataset, $snapFilter), $opts->{H});

            #destination datasets
            for (keys %$backupSet){
                my ($key) = /^(dst_[^_]+)$/ or next;

                #skipping destination if it does not exists
                if (!$backupSet->{$key . '_valid'}){
                    print "*** WARNING: destination '$backupSet->{$key}'"
                        . " does not exist! ***\n\n";
                }
                else{
                    my $dstDataSet = $dataset;
                    $dstDataSet =~ s/^$backupSet->{src}/$backupSet->{$key}/;
                    dumpStats(collectData($dstDataSet, $snapFilter), $opts->{H});
                }
            }

        }
    }
    return 1;
}

main();

1;

__END__

=head1 NAME

znapzendztatz - znapzend statistics utility

=head1 SYNOPSIS

B<znapzendztatz> [I<options>...] [src_dataset]

 -H             do not print headers and separate fields by a single tab
                instead of arbitrary white space
 -r,--recursive show statistics for dataset and sub datasets
 --only-enabled only show statistics for enabled datasets
 --rootExec=x   exec zfs with this command to obtain root privileges (sudo or pfexec)
 --timeWarp=x   act as if you were shifted by x seconds into the future
 --man          show man-page and exit
 -h,--help      display this help and exit

=head1 DESCRIPTION

znapzendztatz shows statistics of snapshots created and storage space usage

=head1 COPYRIGHT

Copyright (c) 2014 by OETIKER+PARTNER AG. All rights reserved.

=head1 LICENSE

This program 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 3 of the License, or (at your option)
any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see L<http://www.gnu.org/licenses/>.

=head1 AUTHOR

S<Tobias Oetiker E<lt>tobi@oetiker.chE<gt>>
S<Dominik Hassler E<lt>hadfl@cpan.orgE<gt>>

=head1 HISTORY

2014-06-29 had Flexible snapshot time format
2014-06-05 had Initial Version

=cut
