#!/usr/bin/perl -w

use Getopt::Long;
use POSIX "sys_wait_h";
use File::Basename;

#globals
my $session_file,
my %config;
my $rc = 0;
my $pid;

if (init()) {
    exit 1;
}

#copy out working dir
$rc = copy_directory(\%config);
if ($rc) {
    print STDERR "WARNING: failed to copy dir to remote node $rc, trying to recover\n";
    
    $rc = recover_from_bad(\%config, $rc);
    exit($rc);
}

#make remote directories
$rc = make_remotedirs(\%config);
if ($rc) {
    print STDERR "WARNING: failed to make remote dir on node $rc, trying to recover\n";
    
    $rc = recover_from_bad(\%config, $rc);
    exit($rc);
}

#mv remote files to remote directories
if ( $config{'COPYBINS'} > 0) {
    $rc = setup_remotedirs(\%config);
    if ($rc) {
       print STDERR "WARNING: failed to move files on remote node $rc, trying to recover\n";
       
       $rc = recover_from_bad(\%config, $rc);
       exit($rc);
    }
}

#done

exit(0);

sub setup_remotedirs {
    my $href = shift;

    my @ionodes = @{$href->{'IONODES'}};
    my @metanodes = @{$href->{'MGR'}};

    my @servers = (@ionodes,@metanodes);
    my $rc = 0;

    my $bin_dir = $href->{'BINDIR'};
    my $storage_dir = $href->{'STORAGE'};
    my $working_dir = $href->{'WORKINGDIR'};

    my $cmd = "%node \'cp -af $working_dir/pvfs2-server $working_dir/pvfs2-ping $working_dir/fs.conf  $bin_dir\'";
   
    $rc = do_remote_command($href->{'RCMDPROG'}, 8, 60, $cmd, undef, undef, @servers);

    

    return($rc);
}

sub make_remotedirs {
    my $href = shift;
    my @servers = (@{$href->{'IONODES'}},@{$href->{'MGR'}});
    my $rc = 0;

    my $bin_dir = $href->{'BINDIR'};
    my $storage_dir = $href->{'STORAGE'};
    my $log_dir = $href->{'SERVERLOG'};

    my $cmd = "%node \'mkdir -p $bin_dir\; mkdir -p $log_dir\'";
   
    $rc = do_remote_command($href->{'RCMDPROG'}, 8, 30, $cmd, undef, undef, @servers);

    return($rc);
}
    
sub copy_directory {
    my $href = shift;
    
    my @ionodes = @{$href->{'IONODES'}};
    my @compnodes = @{$href->{'COMPNODES'}};
    my @metanodes = @{$href->{'MGR'}};
    my $rc = 0;

    my $remote_dir = dir_parent($href->{'WORKINGDIR'});

    my $cmd = $href->{'WORKINGDIR'} . " %node:$remote_dir";

    my @nodes = uniq(sort(@ionodes,@compnodes,@metanodes));
    print "DIST: ON @nodes\n";
    $rc = do_remote_command($href->{'RCPPROG'} . " -r", 8, 60, $cmd, undef, undef, @nodes);

    return($rc);
}



sub usage {

    print<<EOF;
Usage: $prog_name [option]
-s -session       session file for PAV to use
-sd -sessiondir   directory containing session file 'pvfs_autosession'
-rsh              remote shell command to use (default 'ssh')
-rcp              remote copy command to use (default 'scp')
-h -help          display this message
EOF
}

sub init {
    GetOptions(\%args,
	       's|session:s',
	       'sd|sessiondir:s',
	       'rsh:s',
	       'rcp:s',
	       'r|root:s',
	       'h|help'
	       );
    $prog_name = $0;
    $pid = $$;

    if ($args{'h'}) {
	usage();
	return(1);
    }

    if ($args{'s'}) {
	$session_file = $args{'s'};
    } elsif ($args{'sd'}) {
	$session_file = $args{'sd'} . "/pvfs_autosession";
    } else {
	usage();
	return(1);
    }

    if (!-f $session_file) {
	print STDERR "ERROR: cannot find session file: $session_file\n";
	return(1);
    }

    %config = ('RCMDPROG' => "ssh",
	       'RCPPROG' => "scp",
	       'PROGROOT' => "./",
	       'COPYBINS' => 0,
	       );

    $config{'PROGROOT'} = $args{'r'} || real_dir($0) || $config{'PROGROOT'};
    my $prog_root = $config{'PROGROOT'};
    require "$prog_root/pav_lib.pl";

    $rc = read_sessionfile($session_file, \%config);
    if ($rc) {
	print STDERR "ERROR: cannot read session file\n";
	return(1);
    }

    $config{'RCMDPROG'} = $args{'rsh'} || $config{'RCMDPROG'};
    $config{'RCPPROG'} = $args{'rcp'} || $config{'RCPPROG'};

    return(0);
}

sub real_dir {
   my ($file, $reldir, $suffix) = fileparse(shift);
   my ($realdir, $envpwd);

   if ($reldir =~ /^\//) {
      $realdir = $reldir;
   } else {
      if (!$ENV{PWD}) {
         chomp($envpwd = `pwd`);
      } else {
         $envpwd = $ENV{PWD};
      }
      $realdir = $envpwd . "/$reldir";
   }
   $realdir .= '/';
   $realdir =~ s#/./#/#g;
   $realdir =~ s#//#/#g;
   return($realdir);
}
