#!/usr/bin/env perl 

use warnings;
use DBI;

use strict;

use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
use Pod::Usage qw( pod2usage );


use constant DB_SOCKET => '/var/run/mysqld/mysqld.sock';
my $dbname   = 'nebulous';
my $dbserver = $ENV{NEB_DBSERVER};
my $dbuser = $ENV{NEB_USER};
my $dbpass = $ENV{NEB_PASS};
my $db = DBI->connect("DBI:mysql:database=${dbname};host=${dbserver};" .
                   "mysql_socket=" . DB_SOCKET(),
                   ${dbuser},${dbpass},
		   { RaiseError => 1, AutoCommit => 1}
    ) or die "Unable to connect to database $DBI::errstr\n";

my ($host,$min_ins_id,$verbose,$limit,$continue,$alt,$vol_label);
$min_ins_id = 0;
$verbose = 0;
$limit = 10000;
$continue = 0;
$alt = 0;
$vol_label = 0;

GetOptions(
    'host|h=s'      => \$host,
    'min|m=s'       => \$min_ins_id,
    'verbose|v'     => \$verbose,
    'limit|l=s'     => \$limit,
    'continue|c'    => \$continue,
    'alternate|a'   => \$alt,
    'vol_label|L=s'   => \$vol_label,
    ) or pod2usage( 2 );
pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
pod2usage( -msg => "Required options: --host",
	   -exitval => 3) unless
    defined($host);

my $volume = $host . "." . $vol_label;
my $rr;

# Get this host volume
my $vol_id_sth = "SELECT vol_id FROM volume where name = '${volume}'";
my $r_vol      = $db->selectall_arrayref( $vol_id_sth );
unless (defined(${ $r_vol }[0])) {
    die "Volume $volume does not exist.";
}
my $vol_id = shift( @{ ${ $r_vol }[0] });

# Get max ins_id
my $max_id_sth = "SELECT ins_id FROM instance WHERE vol_id = $vol_id ORDER BY ins_id DESC limit 1";
my $r_max_id   = $db->selectall_arrayref( $max_id_sth );
unless (defined(${ $r_max_id }[0])) {
    die "Cannot find max_id";
}
my $max_ins_id = shift( @{ ${ $r_max_id }[0] });

if ($verbose) {
    print "$host $volume $vol_id $min_ins_id $max_ins_id\n";
}


# Get storage node volumes;
my %b_nodes = ();
my $vol_id_sth2 = "SELECT vol_id FROM volume WHERE name LIKE 'ippb%'";
my $r_vol2      = $db->selectall_arrayref( $vol_id_sth2 );
foreach $rr (@{ $r_vol2 }) {
    my $b_vol_id = shift( @{ $rr });
    $b_nodes{$b_vol_id} = 1;
    if ($verbose) {
	print " b_node: $b_vol_id\n";
    }
}

# Get the files on this host
my $number = 0;
do {
    my $ins_id_sth = "SELECT ins_id,so_id,uri FROM instance WHERE vol_id = ${vol_id} AND ins_id > $min_ins_id AND ins_id <= $max_ins_id  LIMIT $limit";
    if ($alt) {
	$ins_id_sth = "SELECT ins_id,so_id,uri,vol_id FROM instance WHERE ins_id > $min_ins_id AND ins_id <= $max_ins_id  LIMIT $limit";
    }
    my $r_ins      = $db->selectall_arrayref( $ins_id_sth );
    my $last_ins_id = $max_ins_id;
    $number = 0;
    foreach $rr (@{ $r_ins }) {
	my ($ins_id,$so_id,$uri,$v_id) = @{ $rr };
	if ($verbose) {
#	print ("  $ins_id $so_id $uri\n");
	}
	$number++;
	$last_ins_id = $ins_id;
	if ($alt) {
	    if ($v_id != $vol_id) { next; }
	}
	if ($uri !~ /ota...fits/) { next; }
	my $have_b_node = 0;
	my ($ext_id,$occ_id,$oth_id,$name,$value) = ('',0,0,'','');
	my $rr2;
	
	my $so_id_sth = "SELECT ext_id,so_id,vol_id,ins_id,name,value FROM storage_object JOIN instance USING(so_id) LEFT JOIN storage_object_xattr USING(so_id) WHERE so_id = ${so_id} AND ins_id != ${ins_id} AND (name IS NULL OR name = 'user.copies')";
	
	my $r_so      = $db->selectall_arrayref( $so_id_sth );
	
	foreach $rr2 (@{ $r_so }) {
	    ($ext_id,$so_id,$occ_id,$oth_id,$name,$value) = @{ $rr2 };
	    
	    unless(defined($name)) {
		$name = 'UNDEF';
		$value = 1;
	    }
	    
	    if ($name eq 'user.copies') {
		if ($value == 1) {
		    $have_b_node = 1;
		}
	    }
	    else {
		$have_b_node = 1;
	    }
	    
	    if (defined($b_nodes{$occ_id})) {
		$have_b_node = 1;
	    }
	    if ($verbose) {
		print("   $number $ext_id $so_id $occ_id $oth_id $have_b_node $name $value\n");
	    }
	    
	    if ($have_b_node == 1) {
		last;
	    }
	}
	if ($oth_id) {
	    if ($have_b_node != 1) {
		my $rep_host = int(rand() + 0.5) + 4;
		my $rep_part = int(rand(3));
		my $rep_vol  = "ippb0" . $rep_host . "." . $rep_part;
		
		print("neb-replicate --volume $rep_vol $ext_id\n");
		system("neb-replicate --volume $rep_vol $ext_id");
	    }
	}
	$last_ins_id = $ins_id;
    }
    print "## LAST: $last_ins_id $number\n";
    print "## TRY:  neb_rawOTA_host_scan.pl --host $host --limit $limit --min $last_ins_id\n";
    if ($continue) {
	if ($verbose) {
	    print("RESET $min_ins_id -> $last_ins_id $number\n");
	}
	$min_ins_id = $last_ins_id;
    }
} while (($continue && $number != 0) || ($min_ins_id < $max_ins_id));
