#! /usr/bin/env perl

BEGIN
{
    push(@INC, $ENV{'GLOBUS_LOCATION'} . '/lib/perl');
}

use Globus::Core::Paths;
use IO::File;
use Test;
use File::Path;

my (@tests, @todo) = ();
my $gge = $Globus::Core::Paths::libexecdir . '/globus-gridmap-and-execute';
my $testtmp = &make_tmpdir();
my $verbose = 0;
my $name = (getpwuid($>))[0];
my $test_verbose = $ENV{VERBOSE_TEST} || 0;

@tests = qw(
    test_in_gridmap
    test_not_in_gridmap
    test_hyphen_hyphen
    test_hyphen_hyphen2
    test_invalid_exec
    test_no_args
    test_no_args2
    test_bad_arg
);

sub test_in_gridmap
{
    my $gridmap = "$testtmp/gridmap.test_in_gridmap";
    my $gridmap_file;
    my @cmd = ($gge, '-g', $gridmap, '/bin/true');

    $gridmap_file = new IO::File($gridmap, '>');
    $gridmap_file->print("\"/C=US/O=Globus/O=Grid/CN=Test\" $name\n");
    $gridmap_file->close();

    system { $cmd[0] } @cmd;

    $rc = $? >> 8;

    ok($rc, 0);
}

sub test_not_in_gridmap
{
    my $gridmap = "$testtmp/test_not_in_gridmap";
    my $gridmap_file;
    my @cmd = ($gge, '-g', $gridmap, '/bin/true');

    $gridmap_file = new IO::File($gridmap, '>');
    $gridmap_file->print("\"/C=US/O=Globus/O=Grid/CN=Test\" XXX\n");
    $gridmap_file->close();

    system { $cmd[0] } @cmd;

    $rc = $? >> 8;

    ok($rc, 1);
}

sub test_hyphen_hyphen
{
    my $gridmap = "$testtmp/gridmap.hyphen_hyphen";
    my $gridmap_file;
    my @cmd = ($gge, '-g', $gridmap, '--', '/bin/true', '-g', '/dev/null');

    $gridmap_file = new IO::File($gridmap, '>');
    $gridmap_file->print("\"/C=US/O=Globus/O=Grid/CN=Test\" $name\n");
    $gridmap_file->close();

    system { $cmd[0] } @cmd;

    $rc = $? >> 8;

    ok($rc, 0);
}

sub test_hyphen_hyphen2
{
    my $gridmap = "$testtmp/gridmap.test_hyphen_hyphen2.1";
    my $gridmap2 = "$testtmp/gridmap.test_hyphen_hyphen2.2";
    my $gridmap_file;
    my @cmd = ($gge, '-g', $gridmap, '--', $gge, '-g', $gridmap2, '/bin/true');

    $gridmap_file = new IO::File($gridmap, '>');
    $gridmap_file->print("\"/C=US/O=Globus/O=Grid/CN=Test\" $name\n");
    $gridmap_file->close();

    $gridmap_file = new IO::File($gridmap2, '>');
    $gridmap_file->print("\"/C=US/O=Globus/O=Grid/CN=Test\" XXX\n");
    $gridmap_file->close();

    system { $cmd[0] } @cmd;

    $rc = $? >> 8;

    ok($rc, 1);
}

sub test_invalid_exec
{
    my $gridmap = "$testtmp/test_not_in_gridmap";
    my $gridmap_file;
    my @cmd = ($gge, '-g', $gridmap, '/bin/bogus-exec');

    $gridmap_file = new IO::File($gridmap, '>');
    $gridmap_file->print("\"/C=US/O=Globus/O=Grid/CN=Test\" $name\n");
    $gridmap_file->close();

    system { $cmd[0] } @cmd;

    $rc = $? >> 8;

    ok($rc, 1);
}

sub test_no_args
{
    my @cmd = ($gge);

    system { $cmd[0] } @cmd;

    $rc = $? >> 8;

    ok($rc, 1);
}

sub test_no_args2
{
    my @cmd = ($gge, '--');

    system { $cmd[0] } @cmd;

    $rc = $? >> 8;

    ok($rc, 1);
}

sub test_bad_arg
{
    my @cmd = ($gge, '-k');

    system { $cmd[0] } @cmd;

    $rc = $? >> 8;

    ok($rc, 1);
}

if(@ARGV)
{
    my @doit;

    $verbose = 1;

    foreach(@ARGV)
    {
        if(/^(\d+)-(\d+)$/)
        {
            foreach($1 .. $2)
            {
               push(@doit, $_);
            }
        }
        elsif(/^(\d+)$/)
        {
            push(@doit, $1);
        }
    }
    plan tests => scalar(@doit);

    foreach (@doit)
    {
        eval "&$tests[$_-1]";
    }
}
else
{
    plan tests => scalar(@tests), todo => \@todo;

    foreach (@tests)
    {
	eval "&$_";
    }
}

sub make_tmpdir
{
    my $root;
    my $suffix = '/globus-gridmap-and-execute-test.';
    my $created = 0;
    my $tmpname;
    my @acceptable = split(//, "abcdefghijklmnopqrstuvwxyz".
			       "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
			       "0123456789");
    if(exists($ENV{TMPDIR}))
    {
	$root = $ENV{TMPDIR};
    }
    else
    {
	$root = '/tmp';
    }
    while($created == 0)
    {
	$tmpname = $root . $suffix .
	           $acceptable[rand() * $#acceptable] .
	           $acceptable[rand() * $#acceptable] .
	           $acceptable[rand() * $#acceptable] .
	           $acceptable[rand() * $#acceptable] .
	           $acceptable[rand() * $#acceptable] .
	           $acceptable[rand() * $#acceptable];
	$created = mkdir($tmpname, 0700);
	if($created)
	{
	    if(-l $tmpname or ! -d $tmpname or ! -o $tmpname)
	    {
		$created = 0;
	    }
	}
    }
    return $tmpname;
}

END
{
    if(-d $testtmp and -o $testtmp)
    {
	File::Path::rmtree($testtmp);
    }
}
