#!/usr/bin/perl

#Relies upon libfilesys-df-perl

use strict;
my $has_filesysdf = eval "use Filesys::Df; 1;";
use Switch;

my $rv = 1;

print "=> Checking there is enough free space for a backup...\n\n";

unless ($has_filesysdf) {
    print "!! Perl module Filesys::Df is not installed, exiting and so not completing backup\n\n";
    exit 0;
}

#
# If an argument is given, then this is the backup2l config to test.
#
my $conf = shift @ARGV;
$conf = "/etc/backup2l.conf" unless ($conf);

my $dir;

open my $fh, '<', $conf or die "!! Unable to open file $conf: $!\n\n";

while (<$fh>) {
    next unless ( $_ =~ /^BACKUP_DIR=["']?([^"']+)["']?\s*$/ );

    $dir = $1;
    last;
}

close $fh;

my $ref          = df($dir);
my $divis        = 0;
my $gb_available = $ref->{bavail} / 1e6;

printf "*  Free space on %s: %8.1f GB\n", $dir, $gb_available;

my $est_output = `backup2l --estimate --conf $conf 2> /dev/null`;

unless ( ${^CHILD_ERROR_NATIVE} == 0 ) {
    print "!! backup2l estimate failed: command exited with status $?";
    exit 0;
}

unless ( $est_output =~
    /\/ (?<int>[0-9]*\.?[0-9]+)(?<suff>[ KMGT]B) \(uncompressed\)$/m )
{
    print "!! Failed to parse backup2l output\n\n";
    exit 0;
}

if ( $+{int} eq "0" && $+{suff} eq " B" ) {
    print "!! The backup estimate is 0 bytes which cannot be correct.\n\n";
    exit 0;
}

switch ( $+{suff} ) {
    case " B" { $divis = 1e-9; }
    case "KB" { $divis = 1e-6; }
    case "MB" { $divis = 1e-3; }
    case "GB" { $divis = 1; }
    case "TB" { $divis = 1e3; }
    else      { $divis = 1; }
}

my $value_in_gb = $+{int} * $divis;

printf "*  Estimated backup size:                %8.1f GB\n\n", $value_in_gb;

if ( $gb_available < $value_in_gb ) {
    printf "!! There is not enough space to take a backup.  Aborting!\n\n";
    $rv = 1;
}
else {
    printf "=> There is enough space to take a backup.\n\n";
    $rv = 0;
}

exit $rv;
