#!/usr/bin/perl
#========================================================================
# home brewed tool to reconstruct hardlinks to pool
#========================================================================

use strict;
no  utf8;
use lib "/usr/share/backuppc/lib";
use BackupPC::Lib;
use BackupPC::Attrib;
use BackupPC::PoolWrite;
use BackupPC::FileZIO;

use File::Find;
use File::Path;
use Digest::MD5;

###########################################################################
# Initialize
###########################################################################

die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
my $TopDir = $bpc->TopDir();
my $BinDir = $bpc->BinDir();
my %Conf   = $bpc->Conf();

my $md5 = Digest::MD5->new;

$bpc->ChildInit();

if ( @ARGV != 1 ) {
    print("usage: $0 <host>\n");
    exit(1);
}
if ( $ARGV[0] !~ /^([\w\.\s-]+)$/ ) {
    print("$0: bad host name '$ARGV[0]'\n");
    exit(1);
}
my $host = $1;
my $Dir  = "$TopDir/pc/$host";
my($CurrDumpDir, $Compress);

#
# Re-read config file, so we can include the PC-specific config
#
$bpc->ConfigRead($host);  
%Conf = $bpc->Conf();

###########################################################################
# Process any backups that haven't been linked
###########################################################################
my $md5 = Digest::MD5->new;
my($nFilesNew, $sizeNew, $sizeNewComp);
my($nFilesExist, $sizeExist, $sizeExistComp);

my @Backups = $bpc->BackupInfoRead($host);
$nFilesNew = $sizeNew = $sizeNewComp = 0;
$nFilesExist = $sizeExist = $sizeExistComp = 0;
my($num);
for ( $num = 0 ; $num < @Backups ; $num++ ) {
    $CurrDumpDir = "$Dir/$Backups[$num]{num}";
    print "$CurrDumpDir\n";
    $Compress = $Backups[$num]{compress};
    $Compress or die "for now, only supporting compressed backups\n";
    find(\&wanted, $CurrDumpDir);
}

sub wanted {
    if (-f and not -z and ($_ =~ 'f.*')) { 
	my ($d, $size) = zcat($_);
	my $res = $bpc->MakeFileLink($_, $d, 1, $Compress);
	# my $fn = $File::Find::name;
	# $fn =~ s#/f#/#g;
	# $fn = substr($fn, length($CurrDumpDir)+4);
    }
}

###########################################################################
# Subroutines
###########################################################################

#
# Add a link in the pool to a new file
#
sub LinkNewFile
{
    my($d, $size, $fileName) = @_;
    my $res = $bpc->MakeFileLink($fileName, $d, 1, $Compress);
    if ( $res == 1 ) {
        $nFilesExist++;
        $sizeExist += $size;
        $sizeExistComp += -s $fileName;
    } elsif ( $res == 2 ) {
        $nFilesNew++;
        $sizeNew += $size;
        $sizeNewComp += -s $fileName;
    } elsif ( $res != 0 && $res != -1 ) {
        print("log BackupPC_link got error $res when calling"
             . " MakeFileLink($fileName, $d, 1)\n");
    }
}

sub zcat
{
    my $fileName = $_;
    my $fh = BackupPC::FileZIO->open($fileName, 0, 1);
    my($data, $r, $ret);

    my $size = 0;
    my $buffer = "";

    while ( ($r = $fh->read(\$data, 65536)) > 0 ) { 
	if ($size < 1048576) {
	    $buffer .= $data;
	}
	$size += length($data);
    }
    if ( $r < 0 ) {
        print(STDERR "$0: can't uncompress $fileName\n");
        $ret = 1;
    }
    $fh->close();
    return ($bpc->Buffer2MD5($md5, $size, \$buffer), $size);
}
