package SI::dumper;

use if $ENV{DEBUG} ~~ /dumper|all/ => "Smart::Comments";
use strict;
use warnings;
use SI::tools;
use File::Basename;
use File::Temp qw(tempdir);
use File::Find;

sub dump($\%) {
    my ($file, $devs) = @_;
    my $dumpdates = dirname($file) . "/dumpdates";

    foreach my $volume (
        map { { name => $_, %{ $devs->{volume}{$_} } } }
        keys %{ $devs->{volume} }
      )
    {
        next if !defined $volume->{type} or $volume->{type} !~ /^ext/i;

        verbose("dumping volume $volume->{name}");
        my $dumpdev = $volume->{name};
        my $of = sprintf $file, basename($volume->{name});
        run("dump -D $dumpdates -u -0 -z -f $of $dumpdev");
        verbose("\n");
    }
}

sub restore($\%) {
    my @dumps = glob(shift);
    my $devs = shift;

    my $tmpdir = tempdir (CLEANUP => 0);

    foreach my $dump (@dumps) {
	# suppose it's gzipped
	# find the device
	my $dev;
	my $base = basename($dump);
	find(sub { 
	    return if defined $dev;
	    if ($_ eq $base) {
		$dev = $File::Find::name;
		return;
	    } }, "/dev");
	my $fs = $devs->{volume}{$dev}{type};

	verbose("restore $dump -> $dev : $fs\n");
	run("mount -t $fs $dev $tmpdir");

	eval {
		my $pid = fork or do {
		    open(STDIN, $dump) or die "Can't open $dump as STDIN: $!\n";
		    chdir $tmpdir  or die "Can't chdir to $tmpdir: $!\n";
		    exec restore => "-orf-";
		    die "Can't exec restore: $!\n";
		};
		waitpid($pid, 0);
	};
	run("umount $tmpdir");
	die $@ if $@;
    }
    rmdir($tmpdir);
}


1;

# vim:sts=4 sw=4 aw ai sm:
