#!/usr/bin/perl
use strict;
use warnings;
use File::Basename; 
use Getopt::Long;

my $work_copy_command = '/usr/local/bin/work_copy_as.pl';

sub generate_random_string{
    my $l = shift || 5 ;
    my @chars=('a'..'z','A'..'Z','0'..'9');
    my $random_string;
    foreach (1..$l) {
        # rand @chars will generate a random 
        # number between 0 and scalar @chars
        $random_string .= $chars[rand @chars];
    }
    return $random_string;
}

#Generate the random string
my $random_string=&generate_random_string(11);

sub usage (){
    my $name = basename ($0) ;
    print STDERR <<END;
    
    Usage : $name --username UNAME --report-file REPORT --dataset FILE [OPTIONS]

    -h,--help
        Help
        
    --dataset-list FILE
        Tabular file with absolute path for a list of datasets
        
    --dataset FILE::NAME::EXTENSION
        Path to a dataset file. Multiple --dateset allowed
        
    --report-file FILE
        Output report file
        
    --username UNAME
        username on genotoul (can be an email address, the domain part will
        be removed)

END
    exit(1);
}


main :
{
    my %options;
    Getopt::Long::Configure( 'no_ignorecase', 'bundling' );
    GetOptions (\%options,
        'h|?|help',
        'dataset-list=s',
        'dataset=s@',
        'report-file=s',
        'output-exported-files=s',
        'username=s'
    ) or  usage();
    usage() if (exists $options{'h'}) ;
    
    foreach my $p ( qw/ username report-file output-exported-files/ ) {
        unless( exists($options{$p})) {
            print STDERR "Parameter $p is required\n"  ;
            usage();
        }
    }
    
    unless ($options{'dataset-list'} or $options{'dataset'}) {
        print STDERR "You must use at least one of --dataset-list or --dataset\n";
        usage();
    }
    
    my $dataset_list = $options{'dataset-list'};
    my $ar_dataset = $options{'dataset'} || [] ;
    my $report_file = $options{'report-file'};
    my $exported_file = $options{'output-exported-files'};
    my $username = $options{'username'};
    my @a_dataset = @$ar_dataset ;
    $username =~ s/@.+$//i;
    
    # get all files (path, name and extension)
    my %datasets = ();
    my %checkpath = ();
    my %errored_datasets = ();
    
    if ($dataset_list and -e $dataset_list) {
        open( LIST, "<", $dataset_list) or die "$!";
        while( my $line =<LIST>){
            chomp $line;
            next if ($line=~/^#/);
            #dataset_path extension dataset_name
            my ($dataset_path, $extension, $dataset_name) = split (/\t/, $line, 3);
            $dataset_name ||= 'No_name';
            $dataset_name =~ s/::/_/g;
            push (@a_dataset , join('::', $dataset_path, $dataset_name, $extension  ) );
        }
        close (LIST);
    }
    
    foreach my $param_dataset (@a_dataset) {
        my ($dataset_path, $file_name, $extension) = split ( /::/, $param_dataset, 3);
        $file_name ||= 'No_name';
        #remove all non alphanumeric characters
        $file_name =~ s/[^\w]/_/ig;
        my $key = $file_name ;
        my $c = 1 ;
        while ( exists( $datasets{$key} )) {
            $key = $file_name . "_" . $c ;
            $c++;
        }
        
        # avoid data duplication, pathes
        unless ( exists $checkpath{$dataset_path} ){
            $checkpath{$dataset_path} = 1 ;
            # the file must exists
            if ( -e $dataset_path ) {
                $datasets{$key} = {
                    path        => $dataset_path,
                    name        => $key,
                    extension   => $extension
                };
            }
            else {
                $errored_datasets{$key} = {
                    path        => $dataset_path,
                    name        => $key,
                    extension   => $extension
                };
            }
        }
    }
    
    my $user_work_directory = "/work/$username/";
    my $random_output_dir = 'galaxy-saved-datasets-' . generate_random_string();
    my $dest =  "$user_work_directory/$random_output_dir/";
    while (-d $dest) {
        $random_output_dir = 'galaxy-saved-datasets-' . generate_random_string();
        $dest =  "$user_work_directory/$random_output_dir/";
    }
    
    open(REPORT, '>', $report_file) or die "$!";
    open(EXPORTED, '>', $exported_file) or die "$!";
    print REPORT "Your files have been exported to $dest .\n";

    my $command = "sudo -u $username $work_copy_command -u $username -t $dest ";
    
    foreach my $filename (keys %datasets) {
        my $fpath = $datasets{$filename}{path};
        my $fname = $datasets{$filename}{name};
        my $fext = $datasets{$filename}{extension};
        if ($fname !~ /\.$fext$/ ) {
            $fname .= ".$fext";
        }
        $command .= " " .$fpath . "::" . $fname. " " ;
        print EXPORTED "$dest/$fname\n";
    }
    
    #Command execution 
    system($command) ;
        
    if (%errored_datasets) {
        print REPORT "\n\nnumber of errored datasets : " . scalar( keys %errored_datasets ) . "\n";
        foreach my $filename (keys %errored_datasets) {
            print REPORT join("\t", $errored_datasets{$filename}{path}, $errored_datasets{$filename}{name}, $errored_datasets{$filename}{extension} ) . "\n" ;
        }
    }
    close(REPORT);
    close(EXPORTED);
}
